diff --git a/Batali b/Batali index 17ab717..fe0e52e 100644 --- a/Batali +++ b/Batali @@ -30,12 +30,12 @@ Batali.define do cookbook 'firewall', '~> 2.6.2' cookbook 'chef_nginx', '~> 6.1.1' cookbook 'build-essential', '~> 8.0.3' - cookbook 'mysql', '~> 8.4.0' + cookbook 'mysql', '= 6.1.3' cookbook 'postgresql', '~> 6.1.1' # Deprecated, but wordpress and mediawiki depend on it and it would painful # to change it without moving the databases cookbook 'database' - cookbook 'mysql2_chef_gem', '~> 2.0.1' + cookbook 'mysql2_chef_gem', '= 1.1.0' cookbook 'chef_client_updater', '~> 1.1.1' cookbook 'timezone_iii', '~> 1.0.4' cookbook 'nodejs', '~> 3.0.0' diff --git a/batali.manifest b/batali.manifest index 081a397..b9d75e4 100644 --- a/batali.manifest +++ b/batali.manifest @@ -46,11 +46,11 @@ "dependencies": [ ], - "version": "3.1.0", + "version": "3.3.0", "source": { "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/apache2/versions/3.1.0/download", - "version": "3.1.0" + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/apache2/versions/3.3.0/download", + "version": "3.3.0" } }, { @@ -118,27 +118,27 @@ "name": "windows", "dependencies": [ [ - "chef_handler", - ">= 0.0.0" + "ohai", + ">= 4.0.0" ] ], - "version": "1.38.4", + "version": "3.1.1", "source": { "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/windows/versions/1.38.4/download", - "version": "1.38.4" + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/windows/versions/3.1.1/download", + "version": "3.1.1" } }, { - "name": "chef_handler", + "name": "ohai", "dependencies": [ ], - "version": "1.3.0", + "version": "5.0.4", "source": { "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/chef_handler/versions/1.3.0/download", - "version": "1.3.0" + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/ohai/versions/5.0.4/download", + "version": "5.0.4" } }, { @@ -162,41 +162,86 @@ [ "build-essential", ">= 0.0.0" - ], - [ - "chef-sugar", - ">= 0.0.0" ] ], - "version": "2.0.0", + "version": "3.1.2", "source": { "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/xml/versions/2.0.0/download", - "version": "2.0.0" - } - }, - { - "name": "chef-sugar", - "dependencies": [ - - ], - "version": "3.3.0", - "source": { - "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/chef-sugar/versions/3.3.0/download", - "version": "3.3.0" + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/xml/versions/3.1.2/download", + "version": "3.1.2" } }, { "name": "mysql", "dependencies": [ - + [ + "yum-mysql-community", + ">= 0.0.0" + ], + [ + "smf", + ">= 0.0.0" + ] ], - "version": "8.4.0", + "version": "6.1.3", "source": { "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/mysql/versions/8.4.0/download", - "version": "8.4.0" + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/mysql/versions/6.1.3/download", + "version": "6.1.3" + } + }, + { + "name": "yum-mysql-community", + "dependencies": [ + [ + "compat_resource", + ">= 12.16.3" + ] + ], + "version": "2.1.0", + "source": { + "type": "Batali::Source::Site", + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/yum-mysql-community/versions/2.1.0/download", + "version": "2.1.0" + } + }, + { + "name": "compat_resource", + "dependencies": [ + + ], + "version": "12.19.0", + "source": { + "type": "Batali::Source::Site", + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/compat_resource/versions/12.19.0/download", + "version": "12.19.0" + } + }, + { + "name": "smf", + "dependencies": [ + [ + "rbac", + ">= 1.0.1" + ] + ], + "version": "2.2.8", + "source": { + "type": "Batali::Source::Site", + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/smf/versions/2.2.8/download", + "version": "2.2.8" + } + }, + { + "name": "rbac", + "dependencies": [ + + ], + "version": "1.0.3", + "source": { + "type": "Batali::Source::Site", + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/rbac/versions/1.0.3/download", + "version": "1.0.3" } }, { @@ -234,11 +279,11 @@ ">= 1.0.0" ] ], - "version": "4.0.9", + "version": "6.1.1", "source": { "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/database/versions/4.0.9/download", - "version": "4.0.9" + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/database/versions/6.1.1/download", + "version": "6.1.1" } }, { @@ -264,18 +309,6 @@ "version": "6.1.1" } }, - { - "name": "compat_resource", - "dependencies": [ - - ], - "version": "12.19.0", - "source": { - "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/compat_resource/versions/12.19.0/download", - "version": "12.19.0" - } - }, { "name": "openssl", "dependencies": [ @@ -319,18 +352,6 @@ "version": "6.1.1" } }, - { - "name": "ohai", - "dependencies": [ - - ], - "version": "5.0.4", - "source": { - "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/ohai/versions/5.0.4/download", - "version": "5.0.4" - } - }, { "name": "zypper", "dependencies": [ @@ -348,22 +369,22 @@ "dependencies": [ [ "build-essential", - ">= 2.4.0" + ">= 0.0.0" ], [ "mysql", - ">= 8.2.0" + ">= 6.0" ], [ "mariadb", ">= 0.0.0" ] ], - "version": "2.0.1", + "version": "1.1.0", "source": { "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/mysql2_chef_gem/versions/2.0.1/download", - "version": "2.0.1" + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/mysql2_chef_gem/versions/1.1.0/download", + "version": "1.1.0" } }, { @@ -485,14 +506,14 @@ "dependencies": [ [ "windows", - ">= 1.34.6" + ">= 2.0" ] ], - "version": "5.0.8", + "version": "6.7.1", "source": { "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/iis/versions/5.0.8/download", - "version": "5.0.8" + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/iis/versions/6.7.1/download", + "version": "6.7.1" } }, { @@ -500,11 +521,11 @@ "dependencies": [ ], - "version": "2.0.0", + "version": "2.1.1", "source": { "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/tar/versions/2.0.0/download", - "version": "2.0.0" + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/tar/versions/2.1.1/download", + "version": "2.1.1" } }, { @@ -574,6 +595,18 @@ "version": "1.1.0" } }, + { + "name": "poise", + "dependencies": [ + + ], + "version": "2.8.1", + "source": { + "type": "Batali::Source::Site", + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/poise/versions/2.8.1/download", + "version": "2.8.1" + } + }, { "name": "poise-build-essential", "dependencies": [ @@ -826,18 +859,6 @@ "version": "4.0.0" } }, - { - "name": "poise", - "dependencies": [ - - ], - "version": "2.8.1", - "source": { - "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/poise/versions/2.8.1/download", - "version": "2.8.1" - } - }, { "name": "users", "dependencies": [ @@ -904,6 +925,18 @@ "version": "2.6.2" } }, + { + "name": "chef-sugar", + "dependencies": [ + + ], + "version": "3.3.0", + "source": { + "type": "Batali::Source::Site", + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/chef-sugar/versions/3.3.0/download", + "version": "3.3.0" + } + }, { "name": "chef_client_updater", "dependencies": [ diff --git a/cookbooks/apache2/.foodcritic b/cookbooks/apache2/.foodcritic new file mode 100644 index 0000000..18e0d2e --- /dev/null +++ b/cookbooks/apache2/.foodcritic @@ -0,0 +1,4 @@ +~FC007 +~FC015 +~FC023 +~FC024 diff --git a/cookbooks/apache2/CHANGELOG.md b/cookbooks/apache2/CHANGELOG.md index e89bc99..39af225 100644 --- a/cookbooks/apache2/CHANGELOG.md +++ b/cookbooks/apache2/CHANGELOG.md @@ -2,6 +2,83 @@ apache2 Cookbook Changelog ========================== This file is used to list changes made in each version of the apache2 cookbook. +v3.3.0 (2017-04-11) +------------------- + +- [GH-478] Added support for the amazon platform_family, outside of rhel +- [GH-474] Update Berksfile to allow fetching of newer +- [GH-473] Update copyright header format +- [GH-472] foodcritic: add sous-chefs rules +- add CODE_OF_CONDUCT +- [GH-471] FCGI paths should not be messed with on RHEL/CenOS 7. CentOS 7 (and recent Fedoras) have Apache 2.4, where FCGI socket path and shared memory path is managed adequately without further involvment neccessary (subdirectory is created under /var/run/httpd). +- [GH-470] Remove support for EOL Fedora < 18 / FreeBSD 9 +- [GH-465] Testing updates +- [GH-469] Use the default cookbook style rules +- [GH-460] Serverspec to InSpec migration +- [GH-461] Update comment header format & other cookstyle fixes +- [GH-454] Test in Travis with Chef-DK and a Rakefile +- [GH-455] openSUSE Leap has it's own platform name +- [GH-279] leave stubs for rhel family `conf.d` files to avoid conflicts on package upgrade; no longer remove `conf.d`, just don't use it +- [GH-427] Add option to configure custom log level +- [GH-450] Ensure the lock_dir is owned by www-data for Apache 2.2 and 2.4 on Debian/Ubuntu +- Remove mod_auth_openid tests, as it is not part of the ASF release and plan to drop support for it and right now it is failing our tests +- [GH-440] Update default values in `apache.prefork` section of README +- [GH-443] fixed typo in copyright year +- Test on the latest chef with chef-zero +- Update supported platforms to Ubuntu 16.04, Debian 8.4, Centos 7.2; deprecating Ubuntu 12.04 +- [GH-422] Fix uniq for nil:NilClass error introduced in 3.2.2 +- [GH-423] allow for apache 2.4 usage on rhel < 7.0 +- Cookbook is now part of the sous-chefs, but still maintained by the same folks +- mod_perl: No longer install libapache2-mpm-prefork +- mod_php: renamed mod_php5 to more generic mod_php; using php 7.0 where available + +v3.2.2 (2016-04-13) +------------------- + +- [GH-420] Allow auto-conversion if either of `apache.listen_ports` or `apache.listen_addresses` are set rather than '&&'. This ensures conversion occurs if only one of the two is set. + + +v3.2.1 (2016-04-11) +------------------- + +- [GH-225] notify `restart` instead of `reload` service on `apache_conf`, `apache_config` +- Update to foodcritic 6 + +v3.2.0 (2016-03-26) +------------------- + +- [GH-378] Deprecates `apache.listen_addresses` and `apache.listen_ports` infavor of [GH-409] +- [GH-409] `apache.listen` now accepts an array of `addr:port` strings +- [GH-358] FreeBSD: Update 10.1 support; Adds php 5.6 in collaboration with chef-cookbooks/php#119 +- [GH-394] Have `apache.prefork.serverlimit` set ServerLimit directive on 2.4 +- [GH-363] Escape '.' in regex for .htaccess/.htpasswd files +- [GH-365] Force log directory creation to be recursive +- [GH-368] Change the service creation to use the `apache.service_name` attribute throughout +- [GH-374] Make metadata.rb compatible with chef versions < 12. +- [GH-382] Fixed typo in node['platform_family'] for NameError in `mod_proxy_html` +- [GH-369] README: Added on Ubuntu `mod_fastcgi` requires `multiverse` apt repository to enabled. +- [GH-381] README: Add missing backtick +- [GH-384] README: Fix names for a2enconf and a2disconf +- [GH-393] README: mention availability of `mod_actions` support +- [GH-383] Debian: Add possibility to use other releases via `apache.default_release` +- [GH-377] Restart service when including `mod_headers` to allow healing of failed service because of missing directives. +- [GH-416] Change the default of `apache.mod_fastcgi.install_method` to 'package' all platforms, as `source` is no longer available. +- [GH-401] Move `mod_deflate` to `apache.default_modules` and no longer force installation on `debian` families. +- [GH-386] Do not install an extra mod_ssl package on SUSE Linux Enterprise +- [GH-335] Do not hardcoded reload/restart on more modern rhel platforms, allowing systemd on CentOS 7 +- [GH-375] Install package `mod_ldap` on CentOS 7 (triggered by `apache.version` == 2.4) +- Update `apache.mod_ssl.cipher_suite` to latest from https://bettercrypto.org/ +- README: Re-organize README to make it easier to find usage and remove old references. +- Added new standard and missing modules (Note: these may not be available natively on all operating systems) + * [mod_http2](http://httpd.apache.org/docs/2.4/mod/mod_http2.html) - Support for the HTTP/2 transport layer. (available since 2.4.17) + * [mod_authnz_fcgi](http://httpd.apache.org/docs/2.4/mod/mod_authnz_fcgi.html) - Enable FastCGI authorizer applications to authenticate and/or authorize clients. (available since 2.4.10) + * [mod_cern_meta](http://httpd.apache.org/docs/2.4/mod/mod_cern_meta.html) - CERN httpd metafile semantics + * [mod_ident](http://httpd.apache.org/docs/2.4/mod/mod_ident.html) - RFC 1413 ident lookups + * [mod_privileges](http://httpd.apache.org/docs/2.4/mod/mod_privileges.html) - Support for Solaris privileges and for running virtual hosts under different user IDs. + * [mod_socache_dc](http://httpd.apache.org/docs/2.4/mod/mod_socache_dc.html) - Distcache based shared object cache provider. + * [mod_version](http://httpd.apache.org/docs/2.4/mod/mod_version.html) - Version dependent configuration + * [mod_watchdog](http://httpd.apache.org/docs/2.4/mod/mod_watchdog.html) - Provides infrastructure for other modules to periodically run tasks + v3.1.0 (2015-05-25) ------------------- diff --git a/cookbooks/apache2/CONTRIBUTING.md b/cookbooks/apache2/CONTRIBUTING.md new file mode 100644 index 0000000..b17a5fa --- /dev/null +++ b/cookbooks/apache2/CONTRIBUTING.md @@ -0,0 +1,105 @@ +# Contributing to the apache2 cookbook + +We are glad you want to contribute to the apache2 cookbook! The first +step is the desire to improve the project. + +## Quick-contribute + +* Create an issue on the github [issue tracker](https://github.com/sous-chefs/apache2/issues) +* Link to your patch as a rebased git branch or pull request from the ticket + +We regularly review contributions and will get back to you if we have +any suggestions or concerns. + +### Branches and Commits + +You should submit your patch as a git branch named after the change. + +It is a best practice to have your commit message have a _summary +line_, followed by an empty line and then a brief description of +the commit. This also helps other contributors understand the +purpose of changes to the code. + +Remember that not all users use Chef in the same way or on the same +operating systems as you, so it is helpful to be clear about your use +case and change so they can understand it even when it doesn't apply +to them. + +### Github and Pull Requests + +We don't require you to use Github, and we will even take patch diffs +attached to tickets on the issue tracker. However Github has a lot of +convenient features, such as being able to see a diff of changes +between a pull request and the main repository quickly without +downloading the branch. + +## Functional and Unit Tests + +This cookbook is set up to run tests under +[Test Kitchen](http://kitchen.ci/). It uses serverspec to run +integration tests after the node has been converged to verify that +the state of the node. + +Test kitchen should run completely without exception using the default +[baseboxes provided by Chef](http://chef.github.io/bento/). +Because Test Kitchen creates VirtualBox machines and runs through +every configuration in the .kitchen.yml file, it may take some time for +these tests to complete. + +If your changes are only for a specific recipe, run only its +configuration with Test Kitchen. If you are adding a new recipe, or +other functionality such as a LWRP or definition, please add +appropriate tests and ensure they run with Test Kitchen. + +If any don't pass, investigate them before submitting your patch. + +Any new feature should have unit tests included with the patch with +good code coverage to help protect it from future changes. Similarly, +patches that fix a bug or regression should have a _regression test_. +Simply put, this is a test that would fail without your patch but +passes with it. The goal is to ensure this bug doesn't regress in the +future. Consider a regular expression that doesn't match a certain +pattern that it should, so you provide a patch and a test to ensure +that the part of the code that uses this regular expression works as +expected. Later another contributor may modify this regular expression +in a way that breaks your use cases. The test you wrote will fail, +signalling to them to research your ticket and use case and accounting +for it. + +If you need help writing tests, please ask on the Chef Developer's +mailing list, or https://community-slack.chef.io/ + +## Cookbook Contribution Do's and Don't's + +Please do include tests for your contribution. If you need help, ask +on the +[chef-dev mailing list](http://lists.chef.io/sympa/info/chef-dev) +or the https://community-slack.chef.io/ + +Not all platforms that a cookbook supports may be supported by Test +Kitchen. Please provide evidence of testing your contribution if it +isn't trivial so we don't have to duplicate effort in testing. Chef +10.14+ "doc" formatted output is sufficient. + +Please do indicate new platform (families) or platform versions in the +commit message, and update the relevant ticket. If a contribution adds +new platforms or platform versions, indicate such in the body of the commit message(s). + +Please do use [foodcritic](http://www.foodcritic.io/) to +lint-check the cookbook. Except FC007, it should pass all correctness +rules. FC007 is okay as long as the dependent cookbooks are *required* +for the default behavior of the cookbook, such as to support an +uncommon platform, secondary recipe, etc. + +Please do ensure that your changes do not break or modify behavior for +other platforms supported by the cookbook. For example if your changes +are for Debian, make sure that they do not break on CentOS. + +Please do not modify the version number in the metadata.rb, the maintainer +will select the appropriate version based on the release cycle +information above. + +Please do not update the CHANGELOG.md for a new version. Not all +changes to a cookbook may be merged and released in the same versions. +We will update the CHANGELOG.md when releasing a new version of +the cookbook. diff --git a/cookbooks/apache2/README.md b/cookbooks/apache2/README.md index 6de7c9f..b55bb33 100644 --- a/cookbooks/apache2/README.md +++ b/cookbooks/apache2/README.md @@ -1,9 +1,9 @@ apache2 Cookbook ================ [![Cookbook Version](https://img.shields.io/cookbook/v/apache2.svg?style=flat)](https://supermarket.chef.io/cookbooks/apache2) -[![Build Status](https://travis-ci.org/svanzoest-cookbooks/apache2.svg?branch=master)](https://travis-ci.org/svanzoest-cookbooks/apache2) -[![Dependency Status](http://img.shields.io/gemnasium/svanzoest-cookbooks/apache2.svg?style=flat)](https://gemnasium.com/svanzoest-cookbooks/apache2) -[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/svanzoest-cookbooks/apache2?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) +[![Build Status](https://travis-ci.org/sous-chefs/apache2.svg?branch=master)](https://travis-ci.org/sous-chefs/apache2) +[![Dependency Status](http://img.shields.io/gemnasium/sous-chefs/apache2.svg?style=flat)](https://gemnasium.com/sous-chefs/apache2) +[![License](https://img.shields.io/badge/license-Apache_2-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0) This cookbook provides a complete Debian/Ubuntu style Apache HTTPD configuration. Non-Debian based distributions such as Red Hat/CentOS, @@ -25,20 +25,6 @@ This cookbook ships with templates of these scripts for non Debian/Ubuntu platforms. The scripts are used in the __Definitions__ below. -Requirements -============ - -## Ohai and Chef: - -* Ohai: 0.6.12+ -* Chef: 0.10.10+ - -As of v1.2.0, this cookbook makes use of `node['platform_family']` to -simplify platform selection logic. This attribute was introduced in -Ohai v0.6.12. The recipe methods were introduced in Chef v0.10.10. If -you must run an older version of Chef or Ohai, use [version 1.1.16 of -this cookbook](https://supermarket.chef.io/cookbooks/apache2/versions/1.1.16). - ## Cookbooks: This cookbook has no direct external dependencies. @@ -50,35 +36,32 @@ settings may affect the behavior of this cookbook: * apt cache outdated * SELinux enabled -* IPtables +* firewalls (such as iptables, ufw, etc.) * Compile tools * 3rd party repositories -On Ubuntu/Debian, use Opscode's `apt` cookbook to ensure the package +On Ubuntu/Debian, use [apt](https://supermarket.chef.io/cookbooks/apt) cookbook to ensure the package cache is updated so Chef can install packages, or consider putting apt-get in your bootstrap process or [knife bootstrap template](http://docs.chef.io/knife_bootstrap.html) -On RHEL, SELinux is enabled by default. The `selinux` cookbook +On RHEL, SELinux is enabled by default. The [selinux](https://supermarket.chef.io/cookbooks/selinux) cookbook contains a `permissive` recipe that can be used to set SELinux to "Permissive" state. Otherwise, additional recipes need to be created by the user to address SELinux permissions. -The easiest but **certainly not ideal way** to deal with IPtables is -to flush all rules. Chef Software does provide an `iptables` cookbook but is -migrating from the approach used there to a more robust solution -utilizing a general "firewall" LWRP that would have an "iptables" -provider. Alternately, you can use ufw, with Opscode's `ufw` and -`firewall` cookbooks to set up rules. See those cookbooks' READMEs for -documentation. + +To deal with firewalls Chef Software does provide an [iptables](https://supermarket.chef.io/cookbooks/iptables) and [ufw](https://supermarket.chef.io/cookbooks/ufw) cookbook but is migrating from the approach used there to a more robust solution +utilizing the general [firewall](https://supermarket.chef.io/cookbooks/firewall) cookbook to setup rules. +See those cookbooks' READMEs for documentation. Build/compile tools may not be installed on the system by default. Some recipes (e.g., `apache2::mod_auth_openid`) build the module from -source. Use Opscode's `build-essential` cookbook to get essential +source. Use the [build-essential](https://supermarket.chef.io/cookbooks/build-essential) cookbook to get essential build packages installed. On ArchLinux, if you are using the `apache2::mod_auth_openid` recipe, -you also need the `pacman` cookbook for the `pacman_aur` LWRP. Put +you also need the [pacman](https://supermarket.chef.io/cookbooks/pacman) cookbook for the `pacman_aur` LWRP. Put `recipe[pacman]` on the node's expanded run list (on the node or in a role). This is not an explicit dependency because it is only required for this single recipe and platform; the pacman default recipe @@ -89,20 +72,21 @@ performs `pacman -Sy` to keep pacman's package cache updated. The following platforms and versions are tested and supported using [test-kitchen](http://kitchen.ci/) -* Ubuntu 12.04, 14.04 -* Debian 7.6 -* CentOS 6.5, 7.0 +* Ubuntu 14.04 +* Ubuntu 16.04 +* Debian 8.6 +* CentOS 7.3 +* Fedora 25 The following platform families are supported in the code, and are assumed to work based on the successful testing on Ubuntu and CentOS. * Red Hat (rhel) -* Fedora -* Amazon Linux The following platforms are also supported in the code, have been -tested manually but are not tested under test-kitchen. +tested manually but are not regularly tested under test-kitchen. +* Amazon Linux * SUSE/OpenSUSE * ArchLinux * FreeBSD @@ -112,25 +96,37 @@ tested manually but are not tested under test-kitchen. On Red Hat Enterprise Linux and derivatives, the EPEL repository may be necessary to install packages used in certain recipes. The `apache2::default` recipe, however, does not require any additional -repositories. Opscode's `yum-epel` cookbook can be used to add the +repositories. The [yum-epel](https://supermarket.chef.io/cookbooks/yum-epel) cookbook can be used to add the EPEL repository. See __Examples__ for more information. -### Notes for FreeBSD: - -Version 2.0 has been had some basic testing against FreeBSD 10.0 using -Chef 11.14.2 which has support for pkgng (CHEF-4637). - -Tests +Usage ===== -This cookbook in the -[source repository](https://github.com/svanzoest-cookbooks/apache2/) -contains chefspec, serverspec and cucumber tests. This is an initial proof of -concept that will be fleshed out with more supporting infrastructure -at a future time. +Using this cookbook is relatively straightforward. It is recommended to create +a project or organization specific [wrapper cookbook](https://www.chef.io/blog/2013/12/03/doing-wrapper-cookbooks-right/) +and add the desired recipes to the run list of a node, or create a role. Depending on your +environment, you may have multiple roles that use different recipes +from this cookbook. Adjust any attributes as desired. For example, to +create a basic role for web servers that provide both HTTP and HTTPS: + +```ruby + % cat roles/webserver.rb + name "webserver" + description "Systems that serve HTTP and HTTPS" + run_list( + "recipe[apache2]", + "recipe[apache2::mod_ssl]" + ) + default_attributes( + "apache" => { + "listen" => ["*:80", "*:443"] + } + ) +``` + +For examples of using the definitions in your own recipes, see their +respective sections below. -Please see the CONTRIBUTING file for information on how to add tests -for your contributions. Attributes ========== @@ -164,7 +160,7 @@ the top of the file. * `node['apache']['lib_dir']` - Location for shared libraries * `node['apache']['default_site_enabled']` - Default site enabled. Default is false. * `node['apache']['ext_status']` - if true, enables ExtendedStatus for `mod_status` -* `node['apache']['locale'] - Locale to set in sysconfig or envvars and used for subprocesses and modules (like mod_dav and mod_wsgi). On debian systems Uses system-local if set to 'system', defaults to 'C'. +* `node['apache']['locale']` - Locale to set in sysconfig or envvars and used for subprocesses and modules (like mod_dav and mod_wsgi). On debian systems Uses system-local if set to 'system', defaults to 'C'. General settings ---------------- @@ -173,16 +169,16 @@ These are general settings used in recipes and templates. Default values are noted. * `node['apache']['version']` - Specifing 2.4 triggers apache 2.4 support. If the platform is known during our test to install 2.4 by default, it will be set to 2.4 for you. Otherwise it falls back to 2.2. This value should be specified as a string. -* `node['apache']['listen_addresses']` - Addresses that httpd should listen on. Default is any ("*"). -* `node['apache']['listen_ports']` - Ports that httpd should listen on. Default is port 80. +* `node['apache']['listen']` - Array of address:port combinations that httpd should listen on. Default is any address and port 80 (`["*:80"]`). * `node['apache']['contact']` - Value for ServerAdmin directive. Default "ops@example.com". * `node['apache']['timeout']` - Value for the Timeout directive. Default is 300. * `node['apache']['keepalive']` - Value for the KeepAlive directive. Default is On. * `node['apache']['keepaliverequests']` - Value for MaxKeepAliveRequests. Default is 100. * `node['apache']['keepalivetimeout']` - Value for the KeepAliveTimeout directive. Default is 5. * `node['apache']['sysconfig_additional_params']` - Additionals variables set in sysconfig file. Default is empty. +* `node['apache']['log_level']` - Value for LogLevel directive. Default is 'warn'. * `node['apache']['default_modules']` - Array of module names. Can take "mod_FOO" or "FOO" as names, where FOO is the apache module, e.g. "`mod_status`" or "`status`". -* `node['apache']['mpm']` - With apache.version 2.4, specifies what Multi-Processing Module to enable. Default is "prefork". +* `node['apache']['mpm']` - With apache.version 2.4, specifies what Multi-Processing Module to enable. Defaults to platform default, otherwise it is "prefork" The modules listed in `default_modules` will be included as recipes in `recipe[apache::default]`. @@ -194,8 +190,8 @@ Prefork attributes are used for tuning the Apache HTTPD [prefork MPM](http://htt * `node['apache']['prefork']['startservers']` - initial number of server processes to start. Default is 16. * `node['apache']['prefork']['minspareservers']` - minimum number of spare server processes. Default 16. * `node['apache']['prefork']['maxspareservers']` - maximum number of spare server processes. Default 32. -* `node['apache']['prefork']['serverlimit']` - upper limit on configurable server processes. Default 400. -* `node['apache']['prefork']['maxrequestworkers']` - Maximum number of connections that will be processed simultaneously +* `node['apache']['prefork']['serverlimit']` - upper limit on configurable server processes. Default 256. +* `node['apache']['prefork']['maxrequestworkers']` - Maximum number of connections that will be processed simultaneously. Default 256. * `node['apache']['prefork']['maxconnectionsperchild']` - Maximum number of request a child process will handle. Default 10000. Worker attributes @@ -234,52 +230,12 @@ To use the cookbook with an unsupported mpm (other than prefork, event or worker * set `node['apache']['mpm']` to the name of the module (e.g. `itk`) * in your cookbook, after `include_recipe 'apache2'` use the `apache_module` definition to enable/disable the required module(s) +Module specific attributes +-------------------------- -mod\_auth\_openid attributes ----------------------------- +Some module recipes have their own attributes that can be used to alter and modify the behavior of this cookbook. Please see the sections for the indivual modules below for more information on those attributes. -The following attributes are in the `attributes/mod_auth_openid.rb` -file. Like all Chef attributes files, they are loaded as well, but -they're logistically unrelated to the others, being specific to the -`mod_auth_openid` recipe. -* `node['apache']['mod_auth_openid']['checksum']` - sha256sum of the tarball containing the source. -* `node['apache']['mod_auth_openid']['ref']` - Any sha, tag, or branch found from https://github.com/bmuller/mod_auth_openid -* `node['apache']['mod_auth_openid']['version']` - directory name version within the tarball -* `node['apache']['mod_auth_openid']['cache_dir']` - the cache directory is where the sqlite3 database is stored. It is separate so it can be managed as a directory resource. -* `node['apache']['mod_auth_openid']['dblocation']` - filename of the sqlite3 database used for directive `AuthOpenIDDBLocation`, stored in the `cache_dir` by default. -* `node['apache']['mod_auth_openid']['configure_flags']` - optional array of configure flags passed to the `./configure` step in the compilation of the module. - -mod\_ssl attributes -------------------- - -For general information on this attributes see http://httpd.apache.org/docs/current/mod/mod_ssl.html - -* `node['apache']['mod_ssl']['cipher_suite']` - sets the SSLCiphersuite value to the specified string. The default is - considered "sane" but you may need to change it for your local security policy, e.g. if you have PCI-DSS requirements. Additional - commentary on the - [original pull request](https://github.com/svanzoest-cookbooks/apache2/pull/15#commitcomment-1605406). -* `node['apache']['mod_ssl']['honor_cipher_order']` - Option to prefer the server's cipher preference order. Default 'On'. -* `node['apache']['mod_ssl']['insecure_renegotiation']` - Option to enable support for insecure renegotiation. Default 'Off'. -* `node['apache']['mod_ssl']['strict_sni_vhost_check']` - Whether to allow non-SNI clients to access a name-based virtual host. Default 'Off'. -* `node['apache']['mod_ssl']['session_cache']` - Configures the OCSP stapling cache. Default `shmcb:/var/run/apache2/ssl_scache` -* `node['apache']['mod_ssl']['session_cache_timeout']` - Number of seconds before an SSL session expires in the Session Cache. Default 300. -* `node['apache']['mod_ssl']['compression']` - Enable compression on the SSL level. Default 'Off'. -* `node['apache']['mod_ssl']['use_stapling']` - Enable stapling of OCSP responses in the TLS handshake. Default 'Off'. -* `node['apache']['mod_ssl']['stapling_responder_timeout']` - Timeout for OCSP stapling queries. Default 5 -* `node['apache']['mod_ssl']['stapling_return_responder_errors']` - Pass stapling related OCSP errors on to client. Default 'Off' -* `node['apache']['mod_ssl']['stapling_cache']` - Configures the OCSP stapling cache. Default `shmcb:/var/run/ocsp(128000)` -* `node['apache']['mod_ssl']['pass_phrase_dialog']` - Configures SSLPassPhraseDialog. Default `builtin` -* `node['apache']['mod_ssl']['mutex']` - Configures SSLMutex. Default `file:/var/run/apache2/ssl_mutex` -* `node['apache']['mod_ssl']['directives']` - Hash for add any custom directive. - -For more information on these directives and how to best secure your site see -- https://bettercrypto.org/ -- https://wiki.mozilla.org/Security/Server_Side_TLS -- https://www.insecure.ws/linux/apache_ssl.html -- https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/ -- https://istlsfastyet.com/ -- https://www.ssllabs.com/projects/best-practices/ Recipes ======= @@ -288,7 +244,7 @@ Most of the recipes in the cookbook are for enabling Apache modules. Where additional configuration or behavior is used, it is documented below in more detail. -The following recipes merely enable the specified module: `mod_alias`, +The following recipes merely enable the specified module: `mod_actions`, `mod_alias`, `mod_auth_basic`, `mod_auth_digest`, `mod_authn_file`, `mod_authnz_ldap`, `mod_authz_default`, `mod_authz_groupfile`, `mod_authz_host`, `mod_authz_user`, `mod_autoindex`, `mod_cgi`, `mod_dav_fs`, @@ -335,8 +291,6 @@ https://bugzilla.redhat.com/show_bug.cgi?format=multiple&id=708550 mod\_auth\_openid ----------------- -**Changed via COOK-915** - This recipe compiles the module from source. In addition to `build-essential`, some other packages are included for installation like the GNU C++ compiler and development headers. @@ -354,22 +308,23 @@ a different location than previous versions, see below. It should be a sane default for most platforms, though, see `attributes/mod_auth_openid.rb`. -### Changes from COOK-915: +The following attributes are in the `attributes/mod_auth_openid.rb` file. + +* `node['apache']['mod_auth_openid']['checksum']` - sha256sum of the tarball containing the source. +* `node['apache']['mod_auth_openid']['ref']` - Any sha, tag, or branch found from https://github.com/bmuller/mod_auth_openid +* `node['apache']['mod_auth_openid']['version']` - directory name version within the tarball +* `node['apache']['mod_auth_openid']['cache_dir']` - the cache directory is where the sqlite3 database is stored. It is separate so it can be managed as a directory resource. +* `node['apache']['mod_auth_openid']['dblocation']` - filename of the sqlite3 database used for directive `AuthOpenIDDBLocation`, stored in the `cache_dir` by default. +* `node['apache']['mod_auth_openid']['configure_flags']` - optional array of configure flags passed to the `./configure` step in the compilation of the module. -* `AuthType OpenID` instead of `AuthOpenIDEnabled On`. -* `require user` instead of `AuthOpenIDUserProgram`. -* A bug(?) in `mod_auth_openid` causes it to segfault when attempting - to update the database file if the containing directory is not - writable by the HTTPD process owner (e.g., www-data), even if the - file is writable. In order to not interfere with other settings from - the default recipe in this cookbook, the db file is moved. mod\_fastcgi ------------ Install the fastcgi package and enable the module. -Only work on Debian/Ubuntu +Note: In Ubuntu 14.04, the `libapache2-mod-fastcgi` module is not available by default due to the [Multiverse](https://help.ubuntu.com/community/Repositories/Ubuntu) repositories. +You need to enable the multiverse repositories either from `/etc/apt/sources.list` or use the [apt](https://supermarket.chef.io/cookbooks/apt) cookbook. mod\_fcgid ---------- @@ -377,12 +332,6 @@ mod\_fcgid Installs the fcgi package and enables the module. Requires EPEL on RHEL family. -On RHEL family, this recipe will delete the fcgid.conf and on version -6+, create the /var/run/httpd/mod_fcgid` directory, which prevents the -emergency error: - - [emerg] (2)No such file or directory: mod_fcgid: Can't create shared memory for size XX bytes - mod\_php5 -------- @@ -399,56 +348,44 @@ mod\_ssl -------- Besides installing and enabling `mod_ssl`, this recipe will append -port 443 to the `node['apache']['listen_ports']` attribute array and +port 443 to the `node['apache']['listen']` attributes for all addresses and update the ports.conf. + +* `node['apache']['mod_ssl']['cipher_suite']` - sets the SSLCiphersuite value to the specified string. The default is + considered "sane" but you may need to change it for your local security policy, e.g. if you have PCI-DSS requirements. Additional + commentary on the + [original pull request](https://github.com/sous-chefs/apache2/pull/15#commitcomment-1605406). +* `node['apache']['mod_ssl']['honor_cipher_order']` - Option to prefer the server's cipher preference order. Default 'On'. +* `node['apache']['mod_ssl']['insecure_renegotiation']` - Option to enable support for insecure renegotiation. Default 'Off'. +* `node['apache']['mod_ssl']['strict_sni_vhost_check']` - Whether to allow non-SNI clients to access a name-based virtual host. Default 'Off'. +* `node['apache']['mod_ssl']['session_cache']` - Configures the OCSP stapling cache. Default `shmcb:/var/run/apache2/ssl_scache` +* `node['apache']['mod_ssl']['session_cache_timeout']` - Number of seconds before an SSL session expires in the Session Cache. Default 300. +* `node['apache']['mod_ssl']['compression']` - Enable compression on the SSL level. Default 'Off'. +* `node['apache']['mod_ssl']['use_stapling']` - Enable stapling of OCSP responses in the TLS handshake. Default 'Off'. +* `node['apache']['mod_ssl']['stapling_responder_timeout']` - Timeout for OCSP stapling queries. Default 5 +* `node['apache']['mod_ssl']['stapling_return_responder_errors']` - Pass stapling related OCSP errors on to client. Default 'Off' +* `node['apache']['mod_ssl']['stapling_cache']` - Configures the OCSP stapling cache. Default `shmcb:/var/run/ocsp(128000)` +* `node['apache']['mod_ssl']['pass_phrase_dialog']` - Configures SSLPassPhraseDialog. Default `builtin` +* `node['apache']['mod_ssl']['mutex']` - Configures SSLMutex. Default `file:/var/run/apache2/ssl_mutex` +* `node['apache']['mod_ssl']['directives']` - Hash for add any custom directive. + +For general information on these attributes see http://httpd.apache.org/docs/current/mod/mod_ssl.html + +For more information on these directives and how to best secure your site see +- https://bettercrypto.org/ +- https://wiki.mozilla.org/Security/Server_Side_TLS +- https://www.insecure.ws/linux/apache_ssl.html +- https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/ +- https://istlsfastyet.com/ +- https://www.ssllabs.com/projects/best-practices/ + Definitions =========== The cookbook provides a few definitions. At some point in the future -these definitions may be refactored into lightweight resources and -providers as suggested by -[foodcritic rule FC015](http://acrmp.github.com/foodcritic/#FC015). - -apache\_config ------------- - -Sets up configuration file for Apache from a template. The -template should be in the same cookbook where the definition is used. This is used by the `apache_conf` definition and is not often used directly. - -It will use `a2enconf` and `a2disconf` to control the symlinking of configuration files between `conf-available` and `conf-enabled`. - -Enable or disable an Apache config file in -`#{node['apache']['dir']}/conf-available` by calling `a2enmod` or -`a2dismod` to manage the symbolic link in -`#{node['apache']['dir']}/conf-enabled`. These config files should be created in your cookbook, and placed on the system using `apache_conf` - -### Parameters: - -* `name` - Name of the config enabled or disabled with the `a2enconf` or `a2disconf` scripts. -* `source` - The location of a template file. The default `name.erb`. -* `cookbook` - The cookbook in which the configuration template is located (if it is not located in the current cookbook). The default value is the current cookbook. -* `enable` - Default true, which uses `a2enconf` to enable the config. If false, the config will be disabled with `a2disconf`. - -### Examples: - -Enable the example config. - -`````` - apache_config 'example' do - enable true - end -`````` - -Disable a module: - -`````` - apache_config 'disabled_example' do - enable false - end -`````` - -See the recipes directory for many more examples of `apache_config`. +these definitions will be refactored into custom resources see +[issue 414](https://github.com/sous-chefs/apache2/issues/414). apache\_conf ------------ @@ -462,59 +399,77 @@ This definition should generally be called over `apache_config`. * `name` - Name of the config placed and enabled or disabled with the `a2enconf` or `a2disconf` scripts. * `enable` - Default true, which uses `a2enconf` to enable the config. If false, the config will be disabled with `a2disconf`. * `conf_path` - path to put the config in if you need to override the default `conf-available`. +* `source` - The source configuration template name. The default value is `params[:name].conf.erb` +* `cookbook` - The cookbook in which the configuration template is located. The default value is the current cookbook. ### Examples: Place and enable the example conf: -`````` +```ruby apache_conf 'example' do enable true end -`````` +``` Place and disable (or never enable to begin with) the example conf: -`````` +```ruby apache_conf 'example' do enable false end -`````` +``` Place the example conf, which has a different path than the default (conf-*): -`````` +```ruby apache_conf 'example' do conf_path '/random/example/path' enable false end -`````` +``` -apache\_mod ------------- -Sets up configuration file for an Apache module from a template. The -template should be in the same cookbook where the definition is used. -This is used by the `apache_module` definition and is not often used -directly. +apache\_config (internal) +-------------------------- -This will use a template resource to write the module's configuration -file in the `mods-available` under the Apache configuration directory -(`node['apache']['dir']`). This is a platform-dependent location. See -__apache\_module__. +Sets up configuration file for Apache from a template. The +template should be in the same cookbook where the definition is used. This is used by the `apache_conf` definition and should not be used directly. + +It will use `a2enconf` and `a2disconf` to control the symlinking of configuration files between `conf-available` and `conf-enabled`. + +Enable or disable an Apache config file in +`#{node['apache']['dir']}/conf-available` by calling `a2enconf` or +`a2disconf` to manage the symbolic link in +`#{node['apache']['dir']}/conf-enabled`. These config files should be created in your cookbook, and placed on the system using `apache_conf` ### Parameters: -* `name` - Name of the template. When used from the `apache_module`, - it will use the same name as the module. +* `name` - Name of the config enabled or disabled with the `a2enconf` or `a2disconf` scripts. +* `source` - The location of a template file. The default `name.erb`. +* `cookbook` - The cookbook in which the configuration template is located (if it is not located in the current cookbook). The default value is the current cookbook. +* `enable` - Default true, which uses `a2enconf` to enable the config. If false, the config will be disabled with `a2disconf`. ### Examples: -Create `#{node['apache']['dir']}/mods-available/alias.conf`. +Enable the example config. + +```ruby + apache_config 'example' do + enable true + end +``` + +Disable a module: + +```ruby + apache_config 'disabled_example' do + enable false + end +``` + +See the recipes directory for many more examples of `apache_config`. -`````` - apache_mod "alias" -`````` apache\_module -------------- @@ -538,30 +493,56 @@ the definition is used. See __Examples__. Enable the ssl module, which also has a configuration template in `templates/default/mods/ssl.conf.erb`. -`````` +```ruby apache_module "ssl" do conf true end -`````` +``` Enable the php5 module, which has a different filename than the module default: -`````` +```ruby apache_module "php5" do filename "libphp5.so" end -`````` +``` Disable a module: -`````` +```ruby apache_module "disabled_module" do enable false end -`````` +``` See the recipes directory for many more examples of `apache_module`. +apache\_mod (internal) +---------------------- + +Sets up configuration file for an Apache module from a template. The +template should be in the same cookbook where the definition is used. +This is used by the `apache_module` definition and is not often used +directly. + +This will use a template resource to write the module's configuration +file in the `mods-available` under the Apache configuration directory +(`node['apache']['dir']`). This is a platform-dependent location. See +__apache\_module__. + +### Parameters: + +* `name` - Name of the template. When used from the `apache_module`, + it will use the same name as the module. + +### Examples: + +Create `#{node['apache']['dir']}/mods-available/alias.conf`. + +```ruby + apache_mod "alias" +``` + apache\_site ------------ @@ -619,12 +600,12 @@ The recommended way to use the `web_app` definition is in a application specific The following example would look for a template named 'web_app.conf.erb' in your cookbook containing the apache httpd directives defining the `VirtualHost` that would serve up "my_app". -`````` +```ruby web_app "my_app" do template 'web_app.conf.erb' server_name node['my_app']['hostname'] end -`````` +``` All parameters are passed into the template. You can use whatever you like. The apache2 cookbook comes with a `web_app.conf.erb` template as @@ -640,14 +621,14 @@ an example. The following parameters are used in the template: To use the default web_app, for example: -`````` +```ruby web_app "my_site" do server_name node['hostname'] server_aliases [node['fqdn'], "my-site.example.com"] docroot "/srv/www/my_site" cookbook 'apache2' end -`````` +``` The parameters specified will be used as: @@ -660,32 +641,15 @@ In the template. When you write your own, the `@` is significant. For more information about Definitions and parameters, see the [Chef Wiki](http://docs.chef.io/definitions.html) -Usage +Tests ===== -Using this cookbook is relatively straightforward. Add the desired -recipes to the run list of a node, or create a role. Depending on your -environment, you may have multiple roles that use different recipes -from this cookbook. Adjust any attributes as desired. For example, to -create a basic role for web servers that provide both HTTP and HTTPS: +This cookbook in the [source repository](https://github.com/sous-chefs/apache2/) +contains chefspec, serverspec tests. -`````` - % cat roles/webserver.rb - name "webserver" - description "Systems that serve HTTP and HTTPS" - run_list( - "recipe[apache2]", - "recipe[apache2::mod_ssl]" - ) - default_attributes( - "apache" => { - "listen_ports" => ["80", "443"] - } - ) -`````` +Please see the CONTRIBUTING file for information on how to add tests +for your contributions. -For examples of using the definitions in your own recipes, see their -respective sections above. License and Authors =================== @@ -706,13 +670,15 @@ License and Authors * Author:: Gilles Devaux * Author:: Sander van Zoest * Author:: Taylor Price +* Author:: Ben Dean * Copyright:: 2009-2012, Chef Software, Inc * Copyright:: 2011, Atriso * Copyright:: 2011, CustomInk, LLC. * Copyright:: 2013-2014, OneHealth Solutions, Inc. * Copyright:: 2014, Viverae, Inc. -* Copyright:: 2015, Alexander van Zoest +* Copyright:: 2015-2016, Alexander van Zoest +* Copyright:: 2015, Ontario Systems, LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/attributes/default.rb b/cookbooks/apache2/attributes/default.rb index 043915e..654f753 100644 --- a/cookbooks/apache2/attributes/default.rb +++ b/cookbooks/apache2/attributes/default.rb @@ -1,9 +1,9 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Attributes:: default # -# Copyright 2008-2013, Chef Software, Inc. -# Copyright 2014, Viverae, Inc. +# Copyright:: 2008-2013, Chef Software, Inc. +# Copyright:: 2014, Viverae, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -37,6 +37,12 @@ default['apache']['mpm'] = else 'prefork' end + when 'suse' + 'prefork' + when 'rhel' + 'prefork' + when 'amazon' + 'prefork' else 'prefork' end @@ -54,6 +60,8 @@ default['apache']['version'] = else '2.4' end + when 'amazon' + node['platform_version'].to_f >= 2013.09 ? '2.4' : '2.2' when 'rhel' case node['platform'] when 'amazon' @@ -62,18 +70,15 @@ default['apache']['version'] = node['platform_version'].to_f >= 7.0 ? '2.4' : '2.2' end when 'fedora' - node['platform_version'].to_f >= 18 ? '2.4' : '2.2' + '2.4' when 'suse' case node['platform'] - when 'opensuse' - node['platform_version'].to_f >= 13.1 ? '2.4' : '2.2' - # FIXME: when "suse" for SLES + when 'suse' + node['platform_version'].to_f >= 12.1 ? '2.4' : '2.2' else '2.4' end when 'freebsd' - node['platform_version'].to_f >= 10.0 ? '2.4' : '2.2' - else '2.4' end @@ -83,9 +88,19 @@ default['apache']['default_site_name'] = 'default' # Where the various parts of apache are case node['platform'] when 'redhat', 'centos', 'scientific', 'fedora', 'amazon', 'oracle' - default['apache']['package'] = 'httpd' + if node['platform'] == 'amazon' + if node['apache']['version'] == '2.4' + default['apache']['package'] = 'httpd24' + default['apache']['devel_package'] = 'httpd24-devel' + else + default['apache']['package'] = 'httpd22' + default['apache']['devel_package'] = 'httpd22-devel' + end + else + default['apache']['package'] = 'httpd' + default['apache']['devel_package'] = 'httpd-devel' + end default['apache']['service_name'] = 'httpd' - default['apache']['devel_package'] = 'httpd-devel' default['apache']['perl_pkg'] = 'perl' default['apache']['apachectl'] = '/usr/sbin/apachectl' default['apache']['dir'] = '/etc/httpd' @@ -98,26 +113,24 @@ when 'redhat', 'centos', 'scientific', 'fedora', 'amazon', 'oracle' default['apache']['conf_dir'] = '/etc/httpd/conf' default['apache']['docroot_dir'] = '/var/www/html' default['apache']['cgibin_dir'] = '/var/www/cgi-bin' - if node['apache']['version'] == '2.4' - default['apache']['icondir'] = '/usr/share/httpd/icons' - else - default['apache']['icondir'] = '/var/www/icons' - end + default['apache']['icondir'] = + if node['apache']['version'] == '2.4' + '/usr/share/httpd/icons' + else + '/var/www/icons' + end default['apache']['cache_dir'] = '/var/cache/httpd' default['apache']['run_dir'] = '/var/run/httpd' default['apache']['lock_dir'] = '/var/run/httpd' - if node['platform'] == 'amazon' && node['apache']['version'] == '2.4' - default['apache']['package'] = 'httpd24' - default['apache']['devel_package'] = 'httpd24-devel' - end - if node['platform_version'].to_f >= 6 - default['apache']['pid_file'] = '/var/run/httpd/httpd.pid' - else - default['apache']['pid_file'] = '/var/run/httpd.pid' - end - default['apache']['lib_dir'] = node['kernel']['machine'] =~ /^i[36]86$/ ? '/usr/lib/httpd' : '/usr/lib64/httpd' - default['apache']['libexec_dir'] = "#{node['apache']['lib_dir']}/modules" -when 'suse', 'opensuse' + default['apache']['pid_file'] = + if node['platform_version'].to_f >= 6 + '/var/run/httpd/httpd.pid' + else + '/var/run/httpd.pid' + end + default['apache']['lib_dir'] = node['kernel']['machine'] =~ /^i[36]86$/ ? '/usr/lib/httpd' : '/usr/lib64/httpd' + default['apache']['libexec_dir'] = "#{node['apache']['lib_dir']}/modules" +when 'suse', 'opensuse', 'opensuseleap' default['apache']['package'] = 'apache2' default['apache']['perl_pkg'] = 'perl' default['apache']['devel_package'] = 'httpd-devel' @@ -136,21 +149,23 @@ when 'suse', 'opensuse' default['apache']['cache_dir'] = '/var/cache/apache2' default['apache']['run_dir'] = '/var/run/httpd' default['apache']['lock_dir'] = '/var/run/httpd' - if node['platform_version'].to_f >= 6 - default['apache']['pid_file'] = '/var/run/httpd/httpd.pid' - else - default['apache']['pid_file'] = '/var/run/httpd.pid' - end + default['apache']['pid_file'] = + if node['platform_version'].to_f > 11.4 + '/var/run/httpd.pid' + else + '/var/run/httpd2.pid' + end default['apache']['lib_dir'] = node['kernel']['machine'] =~ /^i[36]86$/ ? '/usr/lib/apache2' : '/usr/lib64/apache2' default['apache']['libexec_dir'] = node['apache']['lib_dir'] when 'debian', 'ubuntu' default['apache']['package'] = 'apache2' default['apache']['perl_pkg'] = 'perl' - if node['apache']['mpm'] == 'prefork' - default['apache']['devel_package'] = 'apache2-prefork-dev' - else - default['apache']['devel_package'] = 'apache2-dev' - end + default['apache']['devel_package'] = + if node['apache']['mpm'] == 'prefork' + 'apache2-prefork-dev' + else + 'apache2-dev' + end default['apache']['apachectl'] = '/usr/sbin/apache2ctl' default['apache']['dir'] = '/etc/apache2' default['apache']['log_dir'] = '/var/log/apache2' @@ -178,7 +193,8 @@ when 'debian', 'ubuntu' default['apache']['libexec_dir'] = "#{node['apache']['lib_dir']}/modules" default['apache']['default_site_name'] = '000-default' when 'arch' - default['apache']['package'] = 'apache' + default['apache']['package'] = 'apache' + default['apache']['service_name'] = 'httpd' default['apache']['perl_pkg'] = 'perl' # default['apache']['apachectl'] = '/usr/sbin/apachectl' default['apache']['dir'] = '/etc/httpd' @@ -197,31 +213,18 @@ when 'arch' default['apache']['lock_dir'] = '/var/run/httpd' default['apache']['pid_file'] = '/var/run/httpd/httpd.pid' default['apache']['lib_dir'] = '/usr/lib/httpd' - default['apache']['libexec_dir'] = "#{node['apache']['lib_dir']}/modules" + default['apache']['libexec_dir'] = "#{node['apache']['lib_dir']}/modules" when 'freebsd' - if node['apache']['version'] == '2.4' - default['apache']['package'] = 'apache24' - default['apache']['dir'] = '/usr/local/etc/apache24' - default['apache']['conf_dir'] = '/usr/local/etc/apache24' - default['apache']['docroot_dir'] = '/usr/local/www/apache24/data' - default['apache']['cgibin_dir'] = '/usr/local/www/apache24/cgi-bin' - default['apache']['icondir'] = '/usr/local/www/apache24/icons' - default['apache']['cache_dir'] = '/var/cache/apache24' - default['apache']['run_dir'] = '/var/run' - default['apache']['lock_dir'] = '/var/run' - default['apache']['lib_dir'] = '/usr/local/libexec/apache24' - else - default['apache']['package'] = 'apache22' - default['apache']['dir'] = '/usr/local/etc/apache22' - default['apache']['conf_dir'] = '/usr/local/etc/apache22' - default['apache']['docroot_dir'] = '/usr/local/www/apache22/data' - default['apache']['cgibin_dir'] = '/usr/local/www/apache22/cgi-bin' - default['apache']['icondir'] = '/usr/local/www/apache22/icons' - default['apache']['cache_dir'] = '/var/cache/apache22' - default['apache']['run_dir'] = '/var/run' - default['apache']['lock_dir'] = '/var/run' - default['apache']['lib_dir'] = '/usr/local/libexec/apache22' - end + default['apache']['package'] = 'apache24' + default['apache']['dir'] = '/usr/local/etc/apache24' + default['apache']['conf_dir'] = '/usr/local/etc/apache24' + default['apache']['docroot_dir'] = '/usr/local/www/apache24/data' + default['apache']['cgibin_dir'] = '/usr/local/www/apache24/cgi-bin' + default['apache']['icondir'] = '/usr/local/www/apache24/icons' + default['apache']['cache_dir'] = '/var/cache/apache24' + default['apache']['run_dir'] = '/var/run' + default['apache']['lock_dir'] = '/var/run' + default['apache']['lib_dir'] = '/usr/local/libexec/apache24' default['apache']['devel_package'] = 'httpd-devel' default['apache']['perl_pkg'] = 'perl5' default['apache']['apachectl'] = '/usr/local/sbin/apachectl' @@ -233,9 +236,9 @@ when 'freebsd' default['apache']['user'] = 'www' default['apache']['group'] = 'www' default['apache']['binary'] = '/usr/local/sbin/httpd' - default['apache']['libexec_dir'] = node['apache']['lib_dir'] + default['apache']['libexec_dir'] = node['apache']['lib_dir'] else - default['apache']['package'] = 'apache2' + default['apache']['package'] = 'apache2' default['apache']['devel_package'] = 'apache2-dev' default['apache']['perl_pkg'] = 'perl' default['apache']['dir'] = '/etc/apache2' @@ -266,8 +269,7 @@ end if node['apache']['service_name'].nil? default['apache']['service_name'] = node['apache']['package'] end -default['apache']['listen_addresses'] = %w(*) -default['apache']['listen_ports'] = %w(80) +default['apache']['listen'] = ['*:80'] default['apache']['contact'] = 'ops@example.com' default['apache']['timeout'] = 300 default['apache']['keepalive'] = 'On' @@ -278,15 +280,14 @@ default['apache']['sysconfig_additional_params'] = {} default['apache']['default_site_enabled'] = false default['apache']['default_site_port'] = '80' default['apache']['access_file_name'] = '.htaccess' +default['apache']['default_release'] = nil +default['apache']['log_level'] = 'warn' # Security default['apache']['servertokens'] = 'Prod' default['apache']['serversignature'] = 'On' default['apache']['traceenable'] = 'Off' -# mod_auth_openids -default['apache']['allowed_openids'] = [] - # mod_status Allow list, space seprated list of allowed entries. default['apache']['status_allow_list'] = '127.0.0.1 ::1' @@ -336,19 +337,19 @@ default['apache']['proxy']['allow_from'] = 'none' # Default modules to enable via include_recipe default['apache']['default_modules'] = %w( status alias auth_basic authn_core authn_file authz_core authz_groupfile - authz_host authz_user autoindex dir env mime negotiation setenvif + authz_host authz_user autoindex deflate dir env mime negotiation setenvif ) %w(log_config logio).each do |log_mod| - default['apache']['default_modules'] << log_mod if %w(rhel fedora suse arch freebsd).include?(node['platform_family']) + default['apache']['default_modules'] << log_mod if %w(rhel amazon fedora suse arch freebsd).include?(node['platform_family']) end if node['apache']['version'] == '2.4' %w(unixd).each do |unix_mod| - default['apache']['default_modules'] << unix_mod if %w(rhel fedora suse arch freebsd).include?(node['platform_family']) + default['apache']['default_modules'] << unix_mod if %w(rhel amazon fedora suse arch freebsd).include?(node['platform_family']) end unless node['platform'] == 'amazon' - default['apache']['default_modules'] << 'systemd' if %w(rhel fedora).include?(node['platform_family']) + default['apache']['default_modules'] << 'systemd' if %w(rhel fedora amazon).include?(node['platform_family']) end end diff --git a/cookbooks/apache2/attributes/mod_auth_cas.rb b/cookbooks/apache2/attributes/mod_auth_cas.rb index 76e9fd6..4684859 100644 --- a/cookbooks/apache2/attributes/mod_auth_cas.rb +++ b/cookbooks/apache2/attributes/mod_auth_cas.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Attributes:: mod_auth_cas # -# Copyright 2013, Chef Software, Inc. +# Copyright:: 2013, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -18,4 +18,4 @@ # default['apache']['mod_auth_cas']['from_source'] = false -default['apache']['mod_auth_cas']['source_revision'] = 'v1.0.8.1' +default['apache']['mod_auth_cas']['source_revision'] = 'v1.0.9.1' diff --git a/cookbooks/apache2/attributes/mod_auth_openid.rb b/cookbooks/apache2/attributes/mod_auth_openid.rb index 4436d69..a3812be 100644 --- a/cookbooks/apache2/attributes/mod_auth_openid.rb +++ b/cookbooks/apache2/attributes/mod_auth_openid.rb @@ -1,8 +1,9 @@ # -# Cookbook Name:: apache2 -# Attributes:: mod_auth_cas +# Cookbook:: apache2 +# Attributes:: mod_auth_openid # -# Copyright 2013, Chef Software, Inc. +# Copyright:: 2013, Chef Software, Inc. +# Copyright:: 2014-2016, Alexander van Zoest # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,18 +18,21 @@ # limitations under the License. # +# mod_auth_openids +default['apache']['allowed_openids'] = [] default['apache']['mod_auth_openid']['ref'] = 'v0.8' -default['apache']['mod_auth_openid']['version'] = '0.8' +default['apache']['mod_auth_openid']['version'] = '0.8' default['apache']['mod_auth_openid']['source_url'] = "https://github.com/bmuller/mod_auth_openid/archive/#{node['apache']['mod_auth_openid']['ref']}.tar.gz" default['apache']['mod_auth_openid']['cache_dir'] = '/var/cache/mod_auth_openid' default['apache']['mod_auth_openid']['dblocation'] = "#{node['apache']['mod_auth_openid']['cache_dir']}/mod_auth_openid.db" -case node['platform_family'] -when 'freebsd' - default['apache']['mod_auth_openid']['configure_flags'] = [ - 'CPPFLAGS=-I/usr/local/include', - 'LDFLAGS=-I/usr/local/lib -lsqlite3' - ] -else - default['apache']['mod_auth_openid']['configure_flags'] = [] -end +default['apache']['mod_auth_openid']['configure_flags'] = + case node['platform_family'] + when 'freebsd' + [ + 'CPPFLAGS=-I/usr/local/include', + 'LDFLAGS=-I/usr/local/lib -lsqlite3', + ] + else + [] + end diff --git a/cookbooks/apache2/attributes/mod_fastcgi.rb b/cookbooks/apache2/attributes/mod_fastcgi.rb index 28865b5..b8059ca 100644 --- a/cookbooks/apache2/attributes/mod_fastcgi.rb +++ b/cookbooks/apache2/attributes/mod_fastcgi.rb @@ -1,8 +1,9 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Attributes:: mod_fastcgi # -# Copyright 2013, Chef Software, Inc. +# Copyright:: 2013, Chef Software, Inc. +# Copyright:: 2016, Alexander van Zoest # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -19,3 +20,20 @@ default['apache']['mod_fastcgi']['download_url'] = 'http://www.fastcgi.com/dist/mod_fastcgi-current.tar.gz' default['apache']['mod_fastcgi']['install_method'] = 'package' +default['apache']['mod_fastcgi']['package'] = + case node['platform_family'] + when 'debian' + 'libapache2-mod-fastcgi' + when 'amazon' + 'mod_fastcgi' + when 'rhel' + 'mod_fastcgi' + when 'freebsd' + if node['apache']['version'] == '2.4' + 'ap24-mod_fastcgi' + else + 'ap22-mod_fastcgi' + end + else + 'mod_fastcgi' + end diff --git a/cookbooks/apache2/attributes/mod_pagespeed.rb b/cookbooks/apache2/attributes/mod_pagespeed.rb index 3c23c93..db0f968 100644 --- a/cookbooks/apache2/attributes/mod_pagespeed.rb +++ b/cookbooks/apache2/attributes/mod_pagespeed.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Attributes:: mod_pagespeed # -# Copyright 2013, ZOZI +# Copyright:: 2013, ZOZI # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/attributes/mod_php.rb b/cookbooks/apache2/attributes/mod_php.rb new file mode 100644 index 0000000..6bfbf2f --- /dev/null +++ b/cookbooks/apache2/attributes/mod_php.rb @@ -0,0 +1,34 @@ +# +# Cookbook:: apache2 +# Attributes:: mod_php5 +# +# Copyright:: 2014, Viverae, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +default['apache']['mod_php']['install_method'] = 'package' +default['apache']['mod_php']['module_name'] = 'php5' +default['apache']['mod_php']['so_filename'] = 'libphp5.so' +default['apache']['mod_php']['so_filename'] = 'mod_php5.so' if node['platform_family'] == 'suse' + +if node['platform'] == 'ubuntu' && node['platform_version'].to_f >= 16.04 + default['apache']['mod_php']['module_name'] = 'php7' + default['apache']['mod_php']['so_filename'] = 'libphp7.0.so' +end +if node['platform'] == 'debian' && node['platform_version'].to_f >= 9 + default['apache']['mod_php']['module_name'] = 'php7' + default['apache']['mod_php']['so_filename'] = 'libphp7.0.so' +end +if node['platform'] == 'amazon' && node['apache']['version'] == '2.4' + default['apache']['mod_php']['so_filename'] = 'libphp.so' +end diff --git a/cookbooks/apache2/attributes/mod_ssl.rb b/cookbooks/apache2/attributes/mod_ssl.rb index 061664e..86ab29c 100644 --- a/cookbooks/apache2/attributes/mod_ssl.rb +++ b/cookbooks/apache2/attributes/mod_ssl.rb @@ -1,9 +1,9 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Attributes:: mod_ssl # -# Copyright 2012-2013, Chef Software, Inc. -# Copyright 2014, Viverae, Inc. +# Copyright:: 2012-2013, Chef Software, Inc. +# Copyright:: 2014, Viverae, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -20,12 +20,12 @@ default['apache']['mod_ssl']['port'] = 443 default['apache']['mod_ssl']['protocol'] = 'All -SSLv2 -SSLv3' -default['apache']['mod_ssl']['cipher_suite'] = 'EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH+aRSA+RC4:EECDH:EDH+aRSA:RC4!aNULL!eNULL!LOW!3DES!MD5!EXP!PSK!SRP!DSS' +default['apache']['mod_ssl']['cipher_suite'] = 'EDH+CAMELLIA:EDH+aRSA:EECDH+aRSA+AESGCM:EECDH+aRSA+SHA256:EECDH:+CAMELLIA128:+AES128:+SSLv3:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!DSS:!RC4:!SEED:!IDEA:!ECDSA:kEDH:CAMELLIA128-SHA:AES128-SHA' default['apache']['mod_ssl']['honor_cipher_order'] = 'On' default['apache']['mod_ssl']['insecure_renegotiation'] = 'Off' default['apache']['mod_ssl']['strict_sni_vhost_check'] = 'Off' -default['apache']['mod_ssl']['session_cache'] = 'shmcb:/var/run/apache2/ssl_scache' -default['apache']['mod_ssl']['session_cache_timeout'] = 300 +default['apache']['mod_ssl']['session_cache'] = 'shmcb:/var/run/apache2/ssl_scache' +default['apache']['mod_ssl']['session_cache_timeout'] = 300 default['apache']['mod_ssl']['compression'] = 'Off' default['apache']['mod_ssl']['use_stapling'] = 'Off' default['apache']['mod_ssl']['stapling_responder_timeout'] = 5 @@ -45,8 +45,12 @@ when 'debian' end end when 'freebsd' - default['apache']['mod_ssl']['session_cache'] = 'shmcb:/var/run/ssl_scache(512000)' + default['apache']['mod_ssl']['session_cache'] = 'shmcb:/var/run/ssl_scache(512000)' default['apache']['mod_ssl']['mutex'] = 'file:/var/run/ssl_mutex' +when 'amazon' + if node['apache']['version'] == '2.4' + default['apache']['mod_ssl']['pkg_name'] = 'mod24_ssl' + end when 'rhel', 'fedora', 'suse' case node['platform'] when 'amazon' @@ -54,6 +58,6 @@ when 'rhel', 'fedora', 'suse' default['apache']['mod_ssl']['pkg_name'] = 'mod24_ssl' end end - default['apache']['mod_ssl']['session_cache'] = 'shmcb:/var/cache/mod_ssl/scache(512000)' + default['apache']['mod_ssl']['session_cache'] = 'shmcb:/var/cache/mod_ssl/scache(512000)' default['apache']['mod_ssl']['mutex'] = 'default' end diff --git a/cookbooks/apache2/definitions/apache_conf.rb b/cookbooks/apache2/definitions/apache_conf.rb index ec8d77e..7bbe948 100644 --- a/cookbooks/apache2/definitions/apache_conf.rb +++ b/cookbooks/apache2/definitions/apache_conf.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Definition:: apache_conf # -# Copyright 2008-2013, Chef Software, Inc. +# Copyright:: 2008-2013, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,7 +17,7 @@ # limitations under the License. # -define :apache_conf, :enable => true do +define :apache_conf, enable: true do include_recipe 'apache2::default' conf_name = "#{params[:name]}.conf" @@ -34,7 +34,7 @@ define :apache_conf, :enable => true do group node['apache']['root_group'] backup false mode '0644' - notifies :reload, 'service[apache2]', :delayed + notifies :restart, 'service[apache2]', :delayed end if params[:enable] diff --git a/cookbooks/apache2/definitions/apache_config.rb b/cookbooks/apache2/definitions/apache_config.rb index b28cc3d..ffac01d 100644 --- a/cookbooks/apache2/definitions/apache_config.rb +++ b/cookbooks/apache2/definitions/apache_config.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Definition:: apache_config # -# Copyright 2008-2013, Chef Software, Inc. +# Copyright:: 2008-2013, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,7 +17,7 @@ # limitations under the License. # -define :apache_config, :enable => true do +define :apache_config, enable: true do include_recipe 'apache2::default' conf_name = "#{params[:name]}.conf" @@ -26,7 +26,7 @@ define :apache_config, :enable => true do if params[:enable] execute "a2enconf #{conf_name}" do command "/usr/sbin/a2enconf #{conf_name}" - notifies :reload, 'service[apache2]', :delayed + notifies :restart, 'service[apache2]', :delayed not_if do ::File.symlink?("#{node['apache']['dir']}/conf-enabled/#{conf_name}") && (::File.exist?(params[:conf_path]) ? ::File.symlink?("#{node['apache']['dir']}/conf-enabled/#{conf_name}") : true) diff --git a/cookbooks/apache2/definitions/apache_mod.rb b/cookbooks/apache2/definitions/apache_mod.rb index 5d7656d..b1f8275 100644 --- a/cookbooks/apache2/definitions/apache_mod.rb +++ b/cookbooks/apache2/definitions/apache_mod.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Definition:: apache_mod # -# Copyright 2008-20013, Chef Software, Inc. +# Copyright:: 2008-2013, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/definitions/apache_module.rb b/cookbooks/apache2/definitions/apache_module.rb index 6356020..04ae665 100644 --- a/cookbooks/apache2/definitions/apache_module.rb +++ b/cookbooks/apache2/definitions/apache_module.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Definition:: apache_module # -# Copyright 2008-2013, Chef Software, Inc. +# Copyright:: 2008-2013, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,7 +17,7 @@ # limitations under the License. # -define :apache_module, :enable => true, :conf => false, :restart => false do +define :apache_module, enable: true, conf: false, restart: false do include_recipe 'apache2::default' params[:filename] = params[:filename] || "mod_#{params[:name]}.so" diff --git a/cookbooks/apache2/definitions/apache_site.rb b/cookbooks/apache2/definitions/apache_site.rb index 866076e..8524a99 100644 --- a/cookbooks/apache2/definitions/apache_site.rb +++ b/cookbooks/apache2/definitions/apache_site.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Definition:: apache_site # -# Copyright 2008-2013, Chef Software, Inc. +# Copyright:: 2008-2013, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,7 +17,7 @@ # limitations under the License. # -define :apache_site, :enable => true do +define :apache_site, enable: true do include_recipe 'apache2::default' conf_name = "#{params[:name]}.conf" diff --git a/cookbooks/apache2/definitions/web_app.rb b/cookbooks/apache2/definitions/web_app.rb index 6bb9392..c9784c0 100644 --- a/cookbooks/apache2/definitions/web_app.rb +++ b/cookbooks/apache2/definitions/web_app.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Definition:: web_app # -# Copyright 2008-2013, Chef Software, Inc. +# Copyright:: 2008-2013, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,7 +17,7 @@ # limitations under the License. # -define :web_app, :template => 'web_app.conf.erb', :local => false, :enable => true do +define :web_app, template: 'web_app.conf.erb', local: false, enable: true, server_port: 80 do application_name = params[:name] include_recipe 'apache2::default' @@ -33,8 +33,8 @@ define :web_app, :template => 'web_app.conf.erb', :local => false, :enable => tr mode '0644' cookbook params[:cookbook] if params[:cookbook] variables( - :application_name => application_name, - :params => params + application_name: application_name, + params: params ) if ::File.exist?("#{node['apache']['dir']}/sites-enabled/#{application_name}.conf") notifies :reload, 'service[apache2]', :delayed diff --git a/cookbooks/apache2/libraries/listen.rb b/cookbooks/apache2/libraries/listen.rb new file mode 100644 index 0000000..1c12192 --- /dev/null +++ b/cookbooks/apache2/libraries/listen.rb @@ -0,0 +1,45 @@ +# encoding: utf-8 +# +# Cookbook:: apache2 +# Libraries:: listen +# +# Copyright:: 2015, Ontario Systems, LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +module Apache2 + # Provides method to convert node['apache']['listen_ports'] and node['apache']['listen_addresses'] into new node['apache']['listen'] + module Listen + # @param node [Chef::Node] the chef node + # @return [Hash] a hash indexed by address where the values are arrays of ports to listen to + def merge_listen_attributes(node) + (Apache2::Listen.converted_listen_ports_and_addresses(node) + node['apache']['listen']).uniq + end + + module_function :merge_listen_attributes + + private_class_method + + def self.converted_listen_ports_and_addresses(node) + return [] unless node['apache']['listen_ports'] || node['apache']['listen_addresses'] + Chef::Log.warn "node['apache']['listen_ports'] and node['apache']['listen_addresses'] are deprecated in favor of node['apache']['listen']. Please adjust your cookbooks" + + # Defaults to * for addresses or 80 / 443 for ports if not specified + (node['apache']['listen_addresses'] || %w(*)).uniq.each_with_object([]) do |address, listen| + (node['apache']['listen_ports'] || %w(80 443)).uniq.each do |port| + listen << "#{address}:#{port}" + end + end + end + end +end diff --git a/cookbooks/apache2/metadata.json b/cookbooks/apache2/metadata.json index 9171794..e5fb366 100644 --- a/cookbooks/apache2/metadata.json +++ b/cookbooks/apache2/metadata.json @@ -1 +1 @@ -{"name":"apache2","version":"3.1.0","description":"Installs and configures all aspects of apache2 using Debian style symlinks with helper definitions","long_description":"apache2 Cookbook\n================\n[![Cookbook Version](https://img.shields.io/cookbook/v/apache2.svg?style=flat)](https://supermarket.chef.io/cookbooks/apache2)\n[![Build Status](https://travis-ci.org/svanzoest-cookbooks/apache2.svg?branch=master)](https://travis-ci.org/svanzoest-cookbooks/apache2)\n[![Dependency Status](http://img.shields.io/gemnasium/svanzoest-cookbooks/apache2.svg?style=flat)](https://gemnasium.com/svanzoest-cookbooks/apache2)\n[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/svanzoest-cookbooks/apache2?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)\n\nThis cookbook provides a complete Debian/Ubuntu style Apache HTTPD\nconfiguration. Non-Debian based distributions such as Red Hat/CentOS,\nArchLinux and others supported by this cookbook will have a\nconfiguration that mimics Debian/Ubuntu style as it is easier to\nmanage with Chef.\n\nDebian-style Apache configuration uses scripts to manage modules and\nsites (vhosts). The scripts are:\n\n* a2ensite\n* a2dissite\n* a2enmod\n* a2dismod\n* a2enconf\n* a2disconf\n\nThis cookbook ships with templates of these scripts for non\nDebian/Ubuntu platforms. The scripts are used in the __Definitions__\nbelow.\n\nRequirements\n============\n\n## Ohai and Chef:\n\n* Ohai: 0.6.12+\n* Chef: 0.10.10+\n\nAs of v1.2.0, this cookbook makes use of `node['platform_family']` to\nsimplify platform selection logic. This attribute was introduced in\nOhai v0.6.12. The recipe methods were introduced in Chef v0.10.10. If\nyou must run an older version of Chef or Ohai, use [version 1.1.16 of\nthis cookbook](https://supermarket.chef.io/cookbooks/apache2/versions/1.1.16).\n\n## Cookbooks:\n\nThis cookbook has no direct external dependencies.\n\nDepending on your OS configuration and security policy, you may need\nadditional recipes or cookbooks for this cookbook's recipes to\nconverge on the node. In particular, the following Operating System\nsettings may affect the behavior of this cookbook:\n\n* apt cache outdated\n* SELinux enabled\n* IPtables\n* Compile tools\n* 3rd party repositories\n\nOn Ubuntu/Debian, use Opscode's `apt` cookbook to ensure the package\ncache is updated so Chef can install packages, or consider putting\napt-get in your bootstrap process or\n[knife bootstrap template](http://docs.chef.io/knife_bootstrap.html)\n\nOn RHEL, SELinux is enabled by default. The `selinux` cookbook\ncontains a `permissive` recipe that can be used to set SELinux to\n\"Permissive\" state. Otherwise, additional recipes need to be created\nby the user to address SELinux permissions.\n\nThe easiest but **certainly not ideal way** to deal with IPtables is\nto flush all rules. Chef Software does provide an `iptables` cookbook but is\nmigrating from the approach used there to a more robust solution\nutilizing a general \"firewall\" LWRP that would have an \"iptables\"\nprovider. Alternately, you can use ufw, with Opscode's `ufw` and\n`firewall` cookbooks to set up rules. See those cookbooks' READMEs for\ndocumentation.\n\nBuild/compile tools may not be installed on the system by default.\nSome recipes (e.g., `apache2::mod_auth_openid`) build the module from\nsource. Use Opscode's `build-essential` cookbook to get essential\nbuild packages installed.\n\nOn ArchLinux, if you are using the `apache2::mod_auth_openid` recipe,\nyou also need the `pacman` cookbook for the `pacman_aur` LWRP. Put\n`recipe[pacman]` on the node's expanded run list (on the node or in a\nrole). This is not an explicit dependency because it is only required\nfor this single recipe and platform; the pacman default recipe\nperforms `pacman -Sy` to keep pacman's package cache updated.\n\n## Platforms:\n\nThe following platforms and versions are tested and supported using\n[test-kitchen](http://kitchen.ci/)\n\n* Ubuntu 12.04, 14.04\n* Debian 7.6\n* CentOS 6.5, 7.0\n\nThe following platform families are supported in the code, and are\nassumed to work based on the successful testing on Ubuntu and CentOS.\n\n* Red Hat (rhel)\n* Fedora\n* Amazon Linux\n\nThe following platforms are also supported in the code, have been\ntested manually but are not tested under test-kitchen.\n\n* SUSE/OpenSUSE\n* ArchLinux\n* FreeBSD\n\n### Notes for RHEL Family:\n\nOn Red Hat Enterprise Linux and derivatives, the EPEL repository may\nbe necessary to install packages used in certain recipes. The\n`apache2::default` recipe, however, does not require any additional\nrepositories. Opscode's `yum-epel` cookbook can be used to add the\nEPEL repository. See __Examples__ for more information.\n\n### Notes for FreeBSD:\n\nVersion 2.0 has been had some basic testing against FreeBSD 10.0 using\nChef 11.14.2 which has support for pkgng (CHEF-4637).\n\nTests\n=====\n\nThis cookbook in the\n[source repository](https://github.com/svanzoest-cookbooks/apache2/)\ncontains chefspec, serverspec and cucumber tests. This is an initial proof of\nconcept that will be fleshed out with more supporting infrastructure\nat a future time.\n\nPlease see the CONTRIBUTING file for information on how to add tests\nfor your contributions.\n\nAttributes\n==========\n\nThis cookbook uses many attributes, broken up into a few different\nkinds.\n\nPlatform specific\n-----------------\n\nIn order to support the broadest number of platforms, several\nattributes are determined based on the node's platform. See the\nattributes/default.rb file for default values in the case statement at\nthe top of the file.\n\n* `node['apache']['package']` - Package name for Apache2\n* `node['apache']['perl_pkg']` - Package name for Perl\n* `node['apache']['dir']` - Location for the Apache configuration\n* `node['apache']['log_dir']` - Location for Apache logs\n* `node['apache']['error_log']` - Location for the default error log\n* `node['apache']['access_log']` - Location for the default access log\n* `node['apache']['user']` - User Apache runs as\n* `node['apache']['group']` - Group Apache runs as\n* `node['apache']['binary']` - Apache httpd server daemon\n* `node['apache']['conf_dir']` - Location for the main config file (e.g apache2.conf or httpd.conf)\n* `node['apache']['docroot_dir']` - Location for docroot\n* `node['apache']['cgibin_dir']` - Location for cgi-bin\n* `node['apache']['icondir']` - Location for icons\n* `node['apache']['cache_dir']` - Location for cached files used by Apache itself or recipes\n* `node['apache']['pid_file']` - Location of the PID file for Apache httpd\n* `node['apache']['lib_dir']` - Location for shared libraries\n* `node['apache']['default_site_enabled']` - Default site enabled. Default is false.\n* `node['apache']['ext_status']` - if true, enables ExtendedStatus for `mod_status`\n* `node['apache']['locale'] - Locale to set in sysconfig or envvars and used for subprocesses and modules (like mod_dav and mod_wsgi). On debian systems Uses system-local if set to 'system', defaults to 'C'.\n\nGeneral settings\n----------------\n\nThese are general settings used in recipes and templates. Default\nvalues are noted.\n\n* `node['apache']['version']` - Specifing 2.4 triggers apache 2.4 support. If the platform is known during our test to install 2.4 by default, it will be set to 2.4 for you. Otherwise it falls back to 2.2. This value should be specified as a string.\n* `node['apache']['listen_addresses']` - Addresses that httpd should listen on. Default is any (\"*\").\n* `node['apache']['listen_ports']` - Ports that httpd should listen on. Default is port 80.\n* `node['apache']['contact']` - Value for ServerAdmin directive. Default \"ops@example.com\".\n* `node['apache']['timeout']` - Value for the Timeout directive. Default is 300.\n* `node['apache']['keepalive']` - Value for the KeepAlive directive. Default is On.\n* `node['apache']['keepaliverequests']` - Value for MaxKeepAliveRequests. Default is 100.\n* `node['apache']['keepalivetimeout']` - Value for the KeepAliveTimeout directive. Default is 5.\n* `node['apache']['sysconfig_additional_params']` - Additionals variables set in sysconfig file. Default is empty.\n* `node['apache']['default_modules']` - Array of module names. Can take \"mod_FOO\" or \"FOO\" as names, where FOO is the apache module, e.g. \"`mod_status`\" or \"`status`\".\n* `node['apache']['mpm']` - With apache.version 2.4, specifies what Multi-Processing Module to enable. Default is \"prefork\".\n\nThe modules listed in `default_modules` will be included as recipes in `recipe[apache::default]`.\n\nPrefork attributes\n------------------\n\nPrefork attributes are used for tuning the Apache HTTPD [prefork MPM](http://httpd.apache.org/docs/current/mod/prefork.html) configuration.\n\n* `node['apache']['prefork']['startservers']` - initial number of server processes to start. Default is 16.\n* `node['apache']['prefork']['minspareservers']` - minimum number of spare server processes. Default 16.\n* `node['apache']['prefork']['maxspareservers']` - maximum number of spare server processes. Default 32.\n* `node['apache']['prefork']['serverlimit']` - upper limit on configurable server processes. Default 400.\n* `node['apache']['prefork']['maxrequestworkers']` - Maximum number of connections that will be processed simultaneously\n* `node['apache']['prefork']['maxconnectionsperchild']` - Maximum number of request a child process will handle. Default 10000.\n\nWorker attributes\n-----------------\n\nWorker attributes are used for tuning the Apache HTTPD [worker MPM](http://httpd.apache.org/docs/current/mod/worker.html)\nconfiguration.\n\n* `node['apache']['worker']['startservers']` - Initial number of server processes to start. Default 4\n* `node['apache']['worker']['serverlimit']` - Upper limit on configurable server processes. Default 16.\n* `node['apache']['worker']['minsparethreads']` - Minimum number of spare worker threads. Default 64\n* `node['apache']['worker']['maxsparethreads']` - Maximum number of spare worker threads. Default 192.\n* `node['apache']['worker']['maxrequestworkers']` - Maximum number of simultaneous connections. Default 1024.\n* `node['apache']['worker']['maxconnectionsperchild']` - Limit on the number of connections that an individual child server will handle during its life.\n\nEvent attributes\n----------------\n\nEvent attributes are used for tuning the Apache HTTPD [event MPM](http://httpd.apache.org/docs/current/mod/event.html)\nconfiguration.\n\n* `node['apache']['event']['startservers']` - Initial number of child server processes created at startup. Default 4.\n* `node['apache']['event']['serverlimit']` - Upper limit on configurable number of processes. Default 16.\n* `node['apache']['event']['minsparethreads']` - Minimum number of spare worker threads. Default 64\n* `node['apache']['event']['maxsparethreads']` - Maximum number of spare worker threads. Default 192.\n* `node['apache']['event']['threadlimit']` - Upper limit on the configurable number of threads per child process. Default 192.\n* `node['apache']['event']['threadsperchild']` - Number of threads created by each child process. Default 64.\n* `node['apache']['event']['maxrequestworkers']` - Maximum number of connections that will be processed simultaneously.\n* `node['apache']['event']['maxconnectionsperchild']` - Limit on the number of connections that an individual child server will handle during its life.\n\nOther/Unsupported MPM\n---------------------\n\nTo use the cookbook with an unsupported mpm (other than prefork, event or worker):\n\n* set `node['apache']['mpm']` to the name of the module (e.g. `itk`)\n* in your cookbook, after `include_recipe 'apache2'` use the `apache_module` definition to enable/disable the required module(s)\n\n\nmod\\_auth\\_openid attributes\n----------------------------\n\nThe following attributes are in the `attributes/mod_auth_openid.rb`\nfile. Like all Chef attributes files, they are loaded as well, but\nthey're logistically unrelated to the others, being specific to the\n`mod_auth_openid` recipe.\n\n* `node['apache']['mod_auth_openid']['checksum']` - sha256sum of the tarball containing the source.\n* `node['apache']['mod_auth_openid']['ref']` - Any sha, tag, or branch found from https://github.com/bmuller/mod_auth_openid\n* `node['apache']['mod_auth_openid']['version']` - directory name version within the tarball\n* `node['apache']['mod_auth_openid']['cache_dir']` - the cache directory is where the sqlite3 database is stored. It is separate so it can be managed as a directory resource.\n* `node['apache']['mod_auth_openid']['dblocation']` - filename of the sqlite3 database used for directive `AuthOpenIDDBLocation`, stored in the `cache_dir` by default.\n* `node['apache']['mod_auth_openid']['configure_flags']` - optional array of configure flags passed to the `./configure` step in the compilation of the module.\n\nmod\\_ssl attributes\n-------------------\n\nFor general information on this attributes see http://httpd.apache.org/docs/current/mod/mod_ssl.html\n\n* `node['apache']['mod_ssl']['cipher_suite']` - sets the SSLCiphersuite value to the specified string. The default is\n considered \"sane\" but you may need to change it for your local security policy, e.g. if you have PCI-DSS requirements. Additional\n commentary on the\n [original pull request](https://github.com/svanzoest-cookbooks/apache2/pull/15#commitcomment-1605406).\n* `node['apache']['mod_ssl']['honor_cipher_order']` - Option to prefer the server's cipher preference order. Default 'On'.\n* `node['apache']['mod_ssl']['insecure_renegotiation']` - Option to enable support for insecure renegotiation. Default 'Off'.\n* `node['apache']['mod_ssl']['strict_sni_vhost_check']` - Whether to allow non-SNI clients to access a name-based virtual host. Default 'Off'.\n* `node['apache']['mod_ssl']['session_cache']` - Configures the OCSP stapling cache. Default `shmcb:/var/run/apache2/ssl_scache`\n* `node['apache']['mod_ssl']['session_cache_timeout']` - Number of seconds before an SSL session expires in the Session Cache. Default 300.\n* `node['apache']['mod_ssl']['compression']` - \tEnable compression on the SSL level. Default 'Off'.\n* `node['apache']['mod_ssl']['use_stapling']` - Enable stapling of OCSP responses in the TLS handshake. Default 'Off'.\n* `node['apache']['mod_ssl']['stapling_responder_timeout']` - \tTimeout for OCSP stapling queries. Default 5\n* `node['apache']['mod_ssl']['stapling_return_responder_errors']` - Pass stapling related OCSP errors on to client. Default 'Off'\n* `node['apache']['mod_ssl']['stapling_cache']` - Configures the OCSP stapling cache. Default `shmcb:/var/run/ocsp(128000)`\n* `node['apache']['mod_ssl']['pass_phrase_dialog']` - Configures SSLPassPhraseDialog. Default `builtin`\n* `node['apache']['mod_ssl']['mutex']` - Configures SSLMutex. Default `file:/var/run/apache2/ssl_mutex`\n* `node['apache']['mod_ssl']['directives']` - Hash for add any custom directive.\n\nFor more information on these directives and how to best secure your site see\n- https://bettercrypto.org/\n- https://wiki.mozilla.org/Security/Server_Side_TLS\n- https://www.insecure.ws/linux/apache_ssl.html\n- https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/\n- https://istlsfastyet.com/\n- https://www.ssllabs.com/projects/best-practices/\n\nRecipes\n=======\n\nMost of the recipes in the cookbook are for enabling Apache modules.\nWhere additional configuration or behavior is used, it is documented\nbelow in more detail.\n\nThe following recipes merely enable the specified module: `mod_alias`,\n`mod_auth_basic`, `mod_auth_digest`, `mod_authn_file`, `mod_authnz_ldap`,\n`mod_authz_default`, `mod_authz_groupfile`, `mod_authz_host`,\n`mod_authz_user`, `mod_autoindex`, `mod_cgi`, `mod_dav_fs`,\n`mod_dav_svn`, `mod_deflate`, `mod_dir`, `mod_env`, `mod_expires`,\n`mod_headers`, `mod_ldap`, `mod_log_config`, `mod_mime`,\n`mod_negotiation`, `mod_proxy`, `mod_proxy_ajp`, `mod_proxy_balancer`,\n`mod_proxy_connect`, `mod_proxy_http`, `mod_python`, `mod_rewrite`,\n`mod_setenvif`, `mod_status`, `mod_wsgi`, `mod_xsendfile`.\n\nOn RHEL Family distributions, certain modules ship with a config file\nwith the package. The recipes here may delete those configuration\nfiles to ensure they don't conflict with the settings from the\ncookbook, which will use per-module configuration in\n`/etc/httpd/mods-enabled`.\n\ndefault\n-------\n\nThe default recipe does a number of things to set up Apache HTTPd. It\nalso includes a number of modules based on the attribute\n`node['apache']['default_modules']` as recipes.\n\nmod\\_auth\\_cas\n--------------\n\nThis recipe installs the proper package and enables the `auth_cas`\nmodule. It can install from source or package. Package is the default,\nset the attribute `node['apache']['mod_auth_cas']['from_source']` to\ntrue to enable source installation. Modify the version to install by\nchanging the attribute\n`node['apache']['mod_auth_cas']['source_revision']`. It is a version\ntag by default, but could be master, or another tag, or branch.\n\nThe module configuration is written out with the `CASCookiePath` set,\notherwise an error loading the module may cause Apache to not start.\n\n**Note**: This recipe does not work on EL 6 platforms unless\nepel-testing repository is enabled (outside the scope of this\ncookbook), or the package version 1.0.8.1-3.el6 or higher is otherwise\navailable to the system due to this bug:\n\nhttps://bugzilla.redhat.com/show_bug.cgi?format=multiple&id=708550\n\nmod\\_auth\\_openid\n-----------------\n\n**Changed via COOK-915**\n\nThis recipe compiles the module from source. In addition to\n`build-essential`, some other packages are included for installation\nlike the GNU C++ compiler and development headers.\n\nTo use the module in your own cookbooks to authenticate systems using\nOpenIDs, specify an array of OpenIDs that are allowed to authenticate\nwith the attribute `node['apache']['allowed_openids']`. Use the\nfollowing in a vhost to protect with OpenID authentication:\n\n AuthType OpenID require user <%= node['apache']['allowed_openids'].join(' ') %>\n AuthOpenIDDBLocation <%= node['apache']['mod_auth_openid']['dblocation'] %>\n\nChange the DBLocation with the attribute as required; this file is in\na different location than previous versions, see below. It should be a\nsane default for most platforms, though, see\n`attributes/mod_auth_openid.rb`.\n\n### Changes from COOK-915:\n\n* `AuthType OpenID` instead of `AuthOpenIDEnabled On`.\n* `require user` instead of `AuthOpenIDUserProgram`.\n* A bug(?) in `mod_auth_openid` causes it to segfault when attempting\n to update the database file if the containing directory is not\n writable by the HTTPD process owner (e.g., www-data), even if the\n file is writable. In order to not interfere with other settings from\n the default recipe in this cookbook, the db file is moved.\n\nmod\\_fastcgi\n------------\n\nInstall the fastcgi package and enable the module.\n\nOnly work on Debian/Ubuntu\n\nmod\\_fcgid\n----------\n\nInstalls the fcgi package and enables the module. Requires EPEL on\nRHEL family.\n\nOn RHEL family, this recipe will delete the fcgid.conf and on version\n6+, create the /var/run/httpd/mod_fcgid` directory, which prevents the\nemergency error:\n\n [emerg] (2)No such file or directory: mod_fcgid: Can't create shared memory for size XX bytes\n\nmod\\_php5\n--------\n\nSimply installs the appropriate package on Debian, Ubuntu and\nArchLinux.\n\nOn Red Hat family distributions including Fedora, the php.conf that\ncomes with the package is removed. On RHEL platforms less than v6, the\n`php53` package is used.\n\n* `node['apache']['mod_php5']['install_method']` - default `package` can be overridden to avoid package installs.\n\nmod\\_ssl\n--------\n\nBesides installing and enabling `mod_ssl`, this recipe will append\nport 443 to the `node['apache']['listen_ports']` attribute array and\nupdate the ports.conf.\n\nDefinitions\n===========\n\nThe cookbook provides a few definitions. At some point in the future\nthese definitions may be refactored into lightweight resources and\nproviders as suggested by\n[foodcritic rule FC015](http://acrmp.github.com/foodcritic/#FC015).\n\napache\\_config\n------------\n\nSets up configuration file for Apache from a template. The\ntemplate should be in the same cookbook where the definition is used. This is used by the `apache_conf` definition and is not often used directly.\n\nIt will use `a2enconf` and `a2disconf` to control the symlinking of configuration files between `conf-available` and `conf-enabled`.\n\nEnable or disable an Apache config file in\n`#{node['apache']['dir']}/conf-available` by calling `a2enmod` or\n`a2dismod` to manage the symbolic link in\n`#{node['apache']['dir']}/conf-enabled`. These config files should be created in your cookbook, and placed on the system using `apache_conf`\n\n### Parameters:\n\n* `name` - Name of the config enabled or disabled with the `a2enconf` or `a2disconf` scripts.\n* `source` - The location of a template file. The default `name.erb`.\n* `cookbook` - The cookbook in which the configuration template is located (if it is not located in the current cookbook). The default value is the current cookbook.\n* `enable` - Default true, which uses `a2enconf` to enable the config. If false, the config will be disabled with `a2disconf`.\n\n### Examples:\n\nEnable the example config.\n\n``````\n apache_config 'example' do\n enable true\n end\n``````\n\nDisable a module:\n\n``````\n apache_config 'disabled_example' do\n enable false\n end\n``````\n\nSee the recipes directory for many more examples of `apache_config`.\n\napache\\_conf\n------------\n\nWrites conf files to the `conf-available` folder, and passes enabled values to `apache_config`.\n\nThis definition should generally be called over `apache_config`.\n\n### Parameters:\n\n* `name` - Name of the config placed and enabled or disabled with the `a2enconf` or `a2disconf` scripts.\n* `enable` - Default true, which uses `a2enconf` to enable the config. If false, the config will be disabled with `a2disconf`.\n* `conf_path` - path to put the config in if you need to override the default `conf-available`.\n\n### Examples:\n\nPlace and enable the example conf:\n\n``````\n apache_conf 'example' do\n enable true\n end\n``````\n\nPlace and disable (or never enable to begin with) the example conf:\n\n``````\n apache_conf 'example' do\n enable false\n end\n``````\n\nPlace the example conf, which has a different path than the default (conf-*):\n\n``````\n apache_conf 'example' do\n conf_path '/random/example/path'\n enable false\n end\n``````\n\napache\\_mod\n------------\n\nSets up configuration file for an Apache module from a template. The\ntemplate should be in the same cookbook where the definition is used.\nThis is used by the `apache_module` definition and is not often used\ndirectly.\n\nThis will use a template resource to write the module's configuration\nfile in the `mods-available` under the Apache configuration directory\n(`node['apache']['dir']`). This is a platform-dependent location. See\n__apache\\_module__.\n\n### Parameters:\n\n* `name` - Name of the template. When used from the `apache_module`,\n it will use the same name as the module.\n\n### Examples:\n\nCreate `#{node['apache']['dir']}/mods-available/alias.conf`.\n\n``````\n apache_mod \"alias\"\n``````\n\napache\\_module\n--------------\n\nEnable or disable an Apache module in\n`#{node['apache']['dir']}/mods-available` by calling `a2enmod` or\n`a2dismod` to manage the symbolic link in\n`#{node['apache']['dir']}/mods-enabled`. If the module has a\nconfiguration file, a template should be created in the cookbook where\nthe definition is used. See __Examples__.\n\n### Parameters:\n\n* `name` - Name of the module enabled or disabled with the `a2enmod` or `a2dismod` scripts.\n* `identifier` - String to identify the module for the `LoadModule` directive. Not typically needed, defaults to `#{name}_module`\n* `enable` - Default true, which uses `a2enmod` to enable the module. If false, the module will be disabled with `a2dismod`.\n* `conf` - Default false. Set to true if the module has a config file, which will use `apache_mod` for the file.\n* `filename` - specify the full name of the file, e.g.\n\n### Examples:\n\nEnable the ssl module, which also has a configuration template in `templates/default/mods/ssl.conf.erb`.\n\n``````\n apache_module \"ssl\" do\n conf true\n end\n``````\n\nEnable the php5 module, which has a different filename than the module default:\n\n``````\n apache_module \"php5\" do\n filename \"libphp5.so\"\n end\n``````\n\nDisable a module:\n\n``````\n apache_module \"disabled_module\" do\n enable false\n end\n``````\n\nSee the recipes directory for many more examples of `apache_module`.\n\napache\\_site\n------------\n\nEnable or disable a VirtualHost in\n`#{node['apache']['dir']}/sites-available` by calling a2ensite or\na2dissite to manage the symbolic link in\n`#{node['apache']['dir']}/sites-enabled`.\n\nThe template for the site must be managed as a separate resource. To\ncombine the template with enabling a site, see `web_app`.\n\n### Parameters:\n\n* `name` - Name of the site.\n* `enable` - Default true, which uses `a2ensite` to enable the site. If false, the site will be disabled with `a2dissite`.\n\nweb\\_app\n--------\n\nManage a template resource for a VirtualHost site, and enable it with\n`apache_site`. This is commonly done for managing web applications\nsuch as Ruby on Rails, PHP or Django, and the default behavior\nreflects that. However it is flexible.\n\nThis definition includes some recipes to make sure the system is\nconfigured to have Apache and some sane default modules:\n\n* `apache2`\n* `apache2::mod_rewrite`\n* `apache2::mod_deflate`\n* `apache2::mod_headers`\n\nIt will then configure the template (see __Parameters__ and\n__Examples__ below), and enable or disable the site per the `enable`\nparameter.\n\n### Parameters:\n\nCurrent parameters used by the definition:\n\n* `name` - The name of the site. The template will be written to\n `#{node['apache']['dir']}/sites-available/#{params['name']}.conf`\n* `cookbook` - Optional. Cookbook where the source template is. If\n this is not defined, Chef will use the named template in the\n cookbook where the definition is used.\n* `template` - Default `web_app.conf.erb`, source template file.\n* `enable` - Default true. Passed to the `apache_site` definition.\n\nAdditional parameters can be defined when the definition is called in\na recipe, see __Examples__.\n\n### Examples:\n\nThe recommended way to use the `web_app` definition is in a application specific cookbook named \"my_app\".\nThe following example would look for a template named 'web_app.conf.erb' in your cookbook containing\nthe apache httpd directives defining the `VirtualHost` that would serve up \"my_app\".\n\n``````\n web_app \"my_app\" do\n template 'web_app.conf.erb'\n server_name node['my_app']['hostname']\n end\n``````\n\nAll parameters are passed into the template. You can use whatever you\nlike. The apache2 cookbook comes with a `web_app.conf.erb` template as\nan example. The following parameters are used in the template:\n\n* `server_name` - ServerName directive.\n* `server_aliases` - ServerAlias directive. Must be an array of aliases.\n* `docroot` - DocumentRoot directive.\n* `application_name` - Used in RewriteLog directive. Will be set to the `name` parameter.\n* `directory_index` - Allow overriding the default DirectoryIndex setting, optional\n* `directory_options` - Override Options on the docroot, for example to add parameters like Includes or Indexes, optional.\n* `allow_override` - Modify the AllowOverride directive on the docroot to support apps that need .htaccess to modify configuration or require authentication.\n\nTo use the default web_app, for example:\n\n``````\n web_app \"my_site\" do\n server_name node['hostname']\n server_aliases [node['fqdn'], \"my-site.example.com\"]\n docroot \"/srv/www/my_site\"\n cookbook 'apache2'\n end\n``````\n\nThe parameters specified will be used as:\n\n* `@params[:server_name]`\n* `@params[:server_aliases]`\n* `@params[:docroot]`\n\nIn the template. When you write your own, the `@` is significant.\n\nFor more information about Definitions and parameters, see the\n[Chef Wiki](http://docs.chef.io/definitions.html)\n\nUsage\n=====\n\nUsing this cookbook is relatively straightforward. Add the desired\nrecipes to the run list of a node, or create a role. Depending on your\nenvironment, you may have multiple roles that use different recipes\nfrom this cookbook. Adjust any attributes as desired. For example, to\ncreate a basic role for web servers that provide both HTTP and HTTPS:\n\n``````\n % cat roles/webserver.rb\n name \"webserver\"\n description \"Systems that serve HTTP and HTTPS\"\n run_list(\n \"recipe[apache2]\",\n \"recipe[apache2::mod_ssl]\"\n )\n default_attributes(\n \"apache\" => {\n \"listen_ports\" => [\"80\", \"443\"]\n }\n )\n``````\n\nFor examples of using the definitions in your own recipes, see their\nrespective sections above.\n\nLicense and Authors\n===================\n\n* Author:: Adam Jacob \n* Author:: Joshua Timberman \n* Author:: Bryan McLellan \n* Author:: Dave Esposito \n* Author:: David Abdemoulaie \n* Author:: Edmund Haselwanter \n* Author:: Eric Rochester \n* Author:: Jim Browne \n* Author:: Matthew Kent \n* Author:: Nathen Harvey \n* Author:: Ringo De Smet \n* Author:: Sean OMeara \n* Author:: Seth Chisamore \n* Author:: Gilles Devaux \n* Author:: Sander van Zoest \n* Author:: Taylor Price \n\n* Copyright:: 2009-2012, Chef Software, Inc\n* Copyright:: 2011, Atriso\n* Copyright:: 2011, CustomInk, LLC.\n* Copyright:: 2013-2014, OneHealth Solutions, Inc.\n* Copyright:: 2014, Viverae, Inc.\n* Copyright:: 2015, Alexander van Zoest\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n","maintainer":"Sander van Zoest","maintainer_email":"sander+cookbooks@vanzoest.com","license":"Apache 2.0","platforms":{"debian":">= 0.0.0","ubuntu":">= 0.0.0","redhat":">= 0.0.0","centos":">= 0.0.0","fedora":">= 0.0.0","amazon":">= 0.0.0","scientific":">= 0.0.0","freebsd":">= 0.0.0","suse":">= 0.0.0","opensuse":">= 0.0.0","arch":">= 0.0.0"},"dependencies":{},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{}} \ No newline at end of file +{"name":"apache2","version":"3.3.0","description":"Installs and configures all aspects of apache2 using Debian style symlinks with helper definitions","long_description":"apache2 Cookbook\n================\n[![Cookbook Version](https://img.shields.io/cookbook/v/apache2.svg?style=flat)](https://supermarket.chef.io/cookbooks/apache2)\n[![Build Status](https://travis-ci.org/sous-chefs/apache2.svg?branch=master)](https://travis-ci.org/sous-chefs/apache2)\n[![Dependency Status](http://img.shields.io/gemnasium/sous-chefs/apache2.svg?style=flat)](https://gemnasium.com/sous-chefs/apache2)\n[![License](https://img.shields.io/badge/license-Apache_2-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0)\n\nThis cookbook provides a complete Debian/Ubuntu style Apache HTTPD\nconfiguration. Non-Debian based distributions such as Red Hat/CentOS,\nArchLinux and others supported by this cookbook will have a\nconfiguration that mimics Debian/Ubuntu style as it is easier to\nmanage with Chef.\n\nDebian-style Apache configuration uses scripts to manage modules and\nsites (vhosts). The scripts are:\n\n* a2ensite\n* a2dissite\n* a2enmod\n* a2dismod\n* a2enconf\n* a2disconf\n\nThis cookbook ships with templates of these scripts for non\nDebian/Ubuntu platforms. The scripts are used in the __Definitions__\nbelow.\n\n## Cookbooks:\n\nThis cookbook has no direct external dependencies.\n\nDepending on your OS configuration and security policy, you may need\nadditional recipes or cookbooks for this cookbook's recipes to\nconverge on the node. In particular, the following Operating System\nsettings may affect the behavior of this cookbook:\n\n* apt cache outdated\n* SELinux enabled\n* firewalls (such as iptables, ufw, etc.)\n* Compile tools\n* 3rd party repositories\n\nOn Ubuntu/Debian, use [apt](https://supermarket.chef.io/cookbooks/apt) cookbook to ensure the package\ncache is updated so Chef can install packages, or consider putting\napt-get in your bootstrap process or\n[knife bootstrap template](http://docs.chef.io/knife_bootstrap.html)\n\nOn RHEL, SELinux is enabled by default. The [selinux](https://supermarket.chef.io/cookbooks/selinux) cookbook\ncontains a `permissive` recipe that can be used to set SELinux to\n\"Permissive\" state. Otherwise, additional recipes need to be created\nby the user to address SELinux permissions.\n\n\nTo deal with firewalls Chef Software does provide an [iptables](https://supermarket.chef.io/cookbooks/iptables) and [ufw](https://supermarket.chef.io/cookbooks/ufw) cookbook but is migrating from the approach used there to a more robust solution\nutilizing the general [firewall](https://supermarket.chef.io/cookbooks/firewall) cookbook to setup rules.\nSee those cookbooks' READMEs for documentation.\n\nBuild/compile tools may not be installed on the system by default.\nSome recipes (e.g., `apache2::mod_auth_openid`) build the module from\nsource. Use the [build-essential](https://supermarket.chef.io/cookbooks/build-essential) cookbook to get essential\nbuild packages installed.\n\nOn ArchLinux, if you are using the `apache2::mod_auth_openid` recipe,\nyou also need the [pacman](https://supermarket.chef.io/cookbooks/pacman) cookbook for the `pacman_aur` LWRP. Put\n`recipe[pacman]` on the node's expanded run list (on the node or in a\nrole). This is not an explicit dependency because it is only required\nfor this single recipe and platform; the pacman default recipe\nperforms `pacman -Sy` to keep pacman's package cache updated.\n\n## Platforms:\n\nThe following platforms and versions are tested and supported using\n[test-kitchen](http://kitchen.ci/)\n\n* Ubuntu 14.04\n* Ubuntu 16.04\n* Debian 8.6\n* CentOS 7.3\n* Fedora 25\n\nThe following platform families are supported in the code, and are\nassumed to work based on the successful testing on Ubuntu and CentOS.\n\n* Red Hat (rhel)\n\nThe following platforms are also supported in the code, have been\ntested manually but are not regularly tested under test-kitchen.\n\n* Amazon Linux\n* SUSE/OpenSUSE\n* ArchLinux\n* FreeBSD\n\n### Notes for RHEL Family:\n\nOn Red Hat Enterprise Linux and derivatives, the EPEL repository may\nbe necessary to install packages used in certain recipes. The\n`apache2::default` recipe, however, does not require any additional\nrepositories. The [yum-epel](https://supermarket.chef.io/cookbooks/yum-epel) cookbook can be used to add the\nEPEL repository. See __Examples__ for more information.\n\nUsage\n=====\n\nUsing this cookbook is relatively straightforward. It is recommended to create\na project or organization specific [wrapper cookbook](https://www.chef.io/blog/2013/12/03/doing-wrapper-cookbooks-right/)\nand add the desired recipes to the run list of a node, or create a role. Depending on your\nenvironment, you may have multiple roles that use different recipes\nfrom this cookbook. Adjust any attributes as desired. For example, to\ncreate a basic role for web servers that provide both HTTP and HTTPS:\n\n```ruby\n % cat roles/webserver.rb\n name \"webserver\"\n description \"Systems that serve HTTP and HTTPS\"\n run_list(\n \"recipe[apache2]\",\n \"recipe[apache2::mod_ssl]\"\n )\n default_attributes(\n \"apache\" => {\n \"listen\" => [\"*:80\", \"*:443\"]\n }\n )\n```\n\nFor examples of using the definitions in your own recipes, see their\nrespective sections below.\n\n\nAttributes\n==========\n\nThis cookbook uses many attributes, broken up into a few different\nkinds.\n\nPlatform specific\n-----------------\n\nIn order to support the broadest number of platforms, several\nattributes are determined based on the node's platform. See the\nattributes/default.rb file for default values in the case statement at\nthe top of the file.\n\n* `node['apache']['package']` - Package name for Apache2\n* `node['apache']['perl_pkg']` - Package name for Perl\n* `node['apache']['dir']` - Location for the Apache configuration\n* `node['apache']['log_dir']` - Location for Apache logs\n* `node['apache']['error_log']` - Location for the default error log\n* `node['apache']['access_log']` - Location for the default access log\n* `node['apache']['user']` - User Apache runs as\n* `node['apache']['group']` - Group Apache runs as\n* `node['apache']['binary']` - Apache httpd server daemon\n* `node['apache']['conf_dir']` - Location for the main config file (e.g apache2.conf or httpd.conf)\n* `node['apache']['docroot_dir']` - Location for docroot\n* `node['apache']['cgibin_dir']` - Location for cgi-bin\n* `node['apache']['icondir']` - Location for icons\n* `node['apache']['cache_dir']` - Location for cached files used by Apache itself or recipes\n* `node['apache']['pid_file']` - Location of the PID file for Apache httpd\n* `node['apache']['lib_dir']` - Location for shared libraries\n* `node['apache']['default_site_enabled']` - Default site enabled. Default is false.\n* `node['apache']['ext_status']` - if true, enables ExtendedStatus for `mod_status`\n* `node['apache']['locale']` - Locale to set in sysconfig or envvars and used for subprocesses and modules (like mod_dav and mod_wsgi). On debian systems Uses system-local if set to 'system', defaults to 'C'.\n\nGeneral settings\n----------------\n\nThese are general settings used in recipes and templates. Default\nvalues are noted.\n\n* `node['apache']['version']` - Specifing 2.4 triggers apache 2.4 support. If the platform is known during our test to install 2.4 by default, it will be set to 2.4 for you. Otherwise it falls back to 2.2. This value should be specified as a string.\n* `node['apache']['listen']` - Array of address:port combinations that httpd should listen on. Default is any address and port 80 (`[\"*:80\"]`).\n* `node['apache']['contact']` - Value for ServerAdmin directive. Default \"ops@example.com\".\n* `node['apache']['timeout']` - Value for the Timeout directive. Default is 300.\n* `node['apache']['keepalive']` - Value for the KeepAlive directive. Default is On.\n* `node['apache']['keepaliverequests']` - Value for MaxKeepAliveRequests. Default is 100.\n* `node['apache']['keepalivetimeout']` - Value for the KeepAliveTimeout directive. Default is 5.\n* `node['apache']['sysconfig_additional_params']` - Additionals variables set in sysconfig file. Default is empty.\n* `node['apache']['log_level']` - Value for LogLevel directive. Default is 'warn'.\n* `node['apache']['default_modules']` - Array of module names. Can take \"mod_FOO\" or \"FOO\" as names, where FOO is the apache module, e.g. \"`mod_status`\" or \"`status`\".\n* `node['apache']['mpm']` - With apache.version 2.4, specifies what Multi-Processing Module to enable. Defaults to platform default, otherwise it is \"prefork\"\n\nThe modules listed in `default_modules` will be included as recipes in `recipe[apache::default]`.\n\nPrefork attributes\n------------------\n\nPrefork attributes are used for tuning the Apache HTTPD [prefork MPM](http://httpd.apache.org/docs/current/mod/prefork.html) configuration.\n\n* `node['apache']['prefork']['startservers']` - initial number of server processes to start. Default is 16.\n* `node['apache']['prefork']['minspareservers']` - minimum number of spare server processes. Default 16.\n* `node['apache']['prefork']['maxspareservers']` - maximum number of spare server processes. Default 32.\n* `node['apache']['prefork']['serverlimit']` - upper limit on configurable server processes. Default 256.\n* `node['apache']['prefork']['maxrequestworkers']` - Maximum number of connections that will be processed simultaneously. Default 256.\n* `node['apache']['prefork']['maxconnectionsperchild']` - Maximum number of request a child process will handle. Default 10000.\n\nWorker attributes\n-----------------\n\nWorker attributes are used for tuning the Apache HTTPD [worker MPM](http://httpd.apache.org/docs/current/mod/worker.html)\nconfiguration.\n\n* `node['apache']['worker']['startservers']` - Initial number of server processes to start. Default 4\n* `node['apache']['worker']['serverlimit']` - Upper limit on configurable server processes. Default 16.\n* `node['apache']['worker']['minsparethreads']` - Minimum number of spare worker threads. Default 64\n* `node['apache']['worker']['maxsparethreads']` - Maximum number of spare worker threads. Default 192.\n* `node['apache']['worker']['maxrequestworkers']` - Maximum number of simultaneous connections. Default 1024.\n* `node['apache']['worker']['maxconnectionsperchild']` - Limit on the number of connections that an individual child server will handle during its life.\n\nEvent attributes\n----------------\n\nEvent attributes are used for tuning the Apache HTTPD [event MPM](http://httpd.apache.org/docs/current/mod/event.html)\nconfiguration.\n\n* `node['apache']['event']['startservers']` - Initial number of child server processes created at startup. Default 4.\n* `node['apache']['event']['serverlimit']` - Upper limit on configurable number of processes. Default 16.\n* `node['apache']['event']['minsparethreads']` - Minimum number of spare worker threads. Default 64\n* `node['apache']['event']['maxsparethreads']` - Maximum number of spare worker threads. Default 192.\n* `node['apache']['event']['threadlimit']` - Upper limit on the configurable number of threads per child process. Default 192.\n* `node['apache']['event']['threadsperchild']` - Number of threads created by each child process. Default 64.\n* `node['apache']['event']['maxrequestworkers']` - Maximum number of connections that will be processed simultaneously.\n* `node['apache']['event']['maxconnectionsperchild']` - Limit on the number of connections that an individual child server will handle during its life.\n\nOther/Unsupported MPM\n---------------------\n\nTo use the cookbook with an unsupported mpm (other than prefork, event or worker):\n\n* set `node['apache']['mpm']` to the name of the module (e.g. `itk`)\n* in your cookbook, after `include_recipe 'apache2'` use the `apache_module` definition to enable/disable the required module(s)\n\nModule specific attributes\n--------------------------\n\nSome module recipes have their own attributes that can be used to alter and modify the behavior of this cookbook. Please see the sections for the indivual modules below for more information on those attributes.\n\n\n\nRecipes\n=======\n\nMost of the recipes in the cookbook are for enabling Apache modules.\nWhere additional configuration or behavior is used, it is documented\nbelow in more detail.\n\nThe following recipes merely enable the specified module: `mod_actions`, `mod_alias`,\n`mod_auth_basic`, `mod_auth_digest`, `mod_authn_file`, `mod_authnz_ldap`,\n`mod_authz_default`, `mod_authz_groupfile`, `mod_authz_host`,\n`mod_authz_user`, `mod_autoindex`, `mod_cgi`, `mod_dav_fs`,\n`mod_dav_svn`, `mod_deflate`, `mod_dir`, `mod_env`, `mod_expires`,\n`mod_headers`, `mod_ldap`, `mod_log_config`, `mod_mime`,\n`mod_negotiation`, `mod_proxy`, `mod_proxy_ajp`, `mod_proxy_balancer`,\n`mod_proxy_connect`, `mod_proxy_http`, `mod_python`, `mod_rewrite`,\n`mod_setenvif`, `mod_status`, `mod_wsgi`, `mod_xsendfile`.\n\nOn RHEL Family distributions, certain modules ship with a config file\nwith the package. The recipes here may delete those configuration\nfiles to ensure they don't conflict with the settings from the\ncookbook, which will use per-module configuration in\n`/etc/httpd/mods-enabled`.\n\ndefault\n-------\n\nThe default recipe does a number of things to set up Apache HTTPd. It\nalso includes a number of modules based on the attribute\n`node['apache']['default_modules']` as recipes.\n\nmod\\_auth\\_cas\n--------------\n\nThis recipe installs the proper package and enables the `auth_cas`\nmodule. It can install from source or package. Package is the default,\nset the attribute `node['apache']['mod_auth_cas']['from_source']` to\ntrue to enable source installation. Modify the version to install by\nchanging the attribute\n`node['apache']['mod_auth_cas']['source_revision']`. It is a version\ntag by default, but could be master, or another tag, or branch.\n\nThe module configuration is written out with the `CASCookiePath` set,\notherwise an error loading the module may cause Apache to not start.\n\n**Note**: This recipe does not work on EL 6 platforms unless\nepel-testing repository is enabled (outside the scope of this\ncookbook), or the package version 1.0.8.1-3.el6 or higher is otherwise\navailable to the system due to this bug:\n\nhttps://bugzilla.redhat.com/show_bug.cgi?format=multiple&id=708550\n\nmod\\_auth\\_openid\n-----------------\n\nThis recipe compiles the module from source. In addition to\n`build-essential`, some other packages are included for installation\nlike the GNU C++ compiler and development headers.\n\nTo use the module in your own cookbooks to authenticate systems using\nOpenIDs, specify an array of OpenIDs that are allowed to authenticate\nwith the attribute `node['apache']['allowed_openids']`. Use the\nfollowing in a vhost to protect with OpenID authentication:\n\n AuthType OpenID require user <%= node['apache']['allowed_openids'].join(' ') %>\n AuthOpenIDDBLocation <%= node['apache']['mod_auth_openid']['dblocation'] %>\n\nChange the DBLocation with the attribute as required; this file is in\na different location than previous versions, see below. It should be a\nsane default for most platforms, though, see\n`attributes/mod_auth_openid.rb`.\n\nThe following attributes are in the `attributes/mod_auth_openid.rb` file.\n\n* `node['apache']['mod_auth_openid']['checksum']` - sha256sum of the tarball containing the source.\n* `node['apache']['mod_auth_openid']['ref']` - Any sha, tag, or branch found from https://github.com/bmuller/mod_auth_openid\n* `node['apache']['mod_auth_openid']['version']` - directory name version within the tarball\n* `node['apache']['mod_auth_openid']['cache_dir']` - the cache directory is where the sqlite3 database is stored. It is separate so it can be managed as a directory resource.\n* `node['apache']['mod_auth_openid']['dblocation']` - filename of the sqlite3 database used for directive `AuthOpenIDDBLocation`, stored in the `cache_dir` by default.\n* `node['apache']['mod_auth_openid']['configure_flags']` - optional array of configure flags passed to the `./configure` step in the compilation of the module.\n\n\nmod\\_fastcgi\n------------\n\nInstall the fastcgi package and enable the module.\n\nNote: In Ubuntu 14.04, the `libapache2-mod-fastcgi` module is not available by default due to the [Multiverse](https://help.ubuntu.com/community/Repositories/Ubuntu) repositories.\nYou need to enable the multiverse repositories either from `/etc/apt/sources.list` or use the [apt](https://supermarket.chef.io/cookbooks/apt) cookbook.\n\nmod\\_fcgid\n----------\n\nInstalls the fcgi package and enables the module. Requires EPEL on\nRHEL family.\n\nmod\\_php5\n--------\n\nSimply installs the appropriate package on Debian, Ubuntu and\nArchLinux.\n\nOn Red Hat family distributions including Fedora, the php.conf that\ncomes with the package is removed. On RHEL platforms less than v6, the\n`php53` package is used.\n\n* `node['apache']['mod_php5']['install_method']` - default `package` can be overridden to avoid package installs.\n\nmod\\_ssl\n--------\n\nBesides installing and enabling `mod_ssl`, this recipe will append\nport 443 to the `node['apache']['listen']` attributes for all addresses and\nupdate the ports.conf.\n\n\n* `node['apache']['mod_ssl']['cipher_suite']` - sets the SSLCiphersuite value to the specified string. The default is\n considered \"sane\" but you may need to change it for your local security policy, e.g. if you have PCI-DSS requirements. Additional\n commentary on the\n [original pull request](https://github.com/sous-chefs/apache2/pull/15#commitcomment-1605406).\n* `node['apache']['mod_ssl']['honor_cipher_order']` - Option to prefer the server's cipher preference order. Default 'On'.\n* `node['apache']['mod_ssl']['insecure_renegotiation']` - Option to enable support for insecure renegotiation. Default 'Off'.\n* `node['apache']['mod_ssl']['strict_sni_vhost_check']` - Whether to allow non-SNI clients to access a name-based virtual host. Default 'Off'.\n* `node['apache']['mod_ssl']['session_cache']` - Configures the OCSP stapling cache. Default `shmcb:/var/run/apache2/ssl_scache`\n* `node['apache']['mod_ssl']['session_cache_timeout']` - Number of seconds before an SSL session expires in the Session Cache. Default 300.\n* `node['apache']['mod_ssl']['compression']` - \tEnable compression on the SSL level. Default 'Off'.\n* `node['apache']['mod_ssl']['use_stapling']` - Enable stapling of OCSP responses in the TLS handshake. Default 'Off'.\n* `node['apache']['mod_ssl']['stapling_responder_timeout']` - \tTimeout for OCSP stapling queries. Default 5\n* `node['apache']['mod_ssl']['stapling_return_responder_errors']` - Pass stapling related OCSP errors on to client. Default 'Off'\n* `node['apache']['mod_ssl']['stapling_cache']` - Configures the OCSP stapling cache. Default `shmcb:/var/run/ocsp(128000)`\n* `node['apache']['mod_ssl']['pass_phrase_dialog']` - Configures SSLPassPhraseDialog. Default `builtin`\n* `node['apache']['mod_ssl']['mutex']` - Configures SSLMutex. Default `file:/var/run/apache2/ssl_mutex`\n* `node['apache']['mod_ssl']['directives']` - Hash for add any custom directive.\n\nFor general information on these attributes see http://httpd.apache.org/docs/current/mod/mod_ssl.html\n\nFor more information on these directives and how to best secure your site see\n- https://bettercrypto.org/\n- https://wiki.mozilla.org/Security/Server_Side_TLS\n- https://www.insecure.ws/linux/apache_ssl.html\n- https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/\n- https://istlsfastyet.com/\n- https://www.ssllabs.com/projects/best-practices/\n\nDefinitions\n===========\n\nThe cookbook provides a few definitions. At some point in the future\nthese definitions will be refactored into custom resources see\n[issue 414](https://github.com/sous-chefs/apache2/issues/414).\n\napache\\_conf\n------------\n\nWrites conf files to the `conf-available` folder, and passes enabled values to `apache_config`.\n\nThis definition should generally be called over `apache_config`.\n\n### Parameters:\n\n* `name` - Name of the config placed and enabled or disabled with the `a2enconf` or `a2disconf` scripts.\n* `enable` - Default true, which uses `a2enconf` to enable the config. If false, the config will be disabled with `a2disconf`.\n* `conf_path` - path to put the config in if you need to override the default `conf-available`.\n* `source` - The source configuration template name. The default value is `params[:name].conf.erb`\n* `cookbook` - The cookbook in which the configuration template is located. The default value is the current cookbook.\n\n### Examples:\n\nPlace and enable the example conf:\n\n```ruby\n apache_conf 'example' do\n enable true\n end\n```\n\nPlace and disable (or never enable to begin with) the example conf:\n\n```ruby\n apache_conf 'example' do\n enable false\n end\n```\n\nPlace the example conf, which has a different path than the default (conf-*):\n\n```ruby\n apache_conf 'example' do\n conf_path '/random/example/path'\n enable false\n end\n```\n\n\napache\\_config (internal)\n--------------------------\n\nSets up configuration file for Apache from a template. The\ntemplate should be in the same cookbook where the definition is used. This is used by the `apache_conf` definition and should not be used directly.\n\nIt will use `a2enconf` and `a2disconf` to control the symlinking of configuration files between `conf-available` and `conf-enabled`.\n\nEnable or disable an Apache config file in\n`#{node['apache']['dir']}/conf-available` by calling `a2enconf` or\n`a2disconf` to manage the symbolic link in\n`#{node['apache']['dir']}/conf-enabled`. These config files should be created in your cookbook, and placed on the system using `apache_conf`\n\n### Parameters:\n\n* `name` - Name of the config enabled or disabled with the `a2enconf` or `a2disconf` scripts.\n* `source` - The location of a template file. The default `name.erb`.\n* `cookbook` - The cookbook in which the configuration template is located (if it is not located in the current cookbook). The default value is the current cookbook.\n* `enable` - Default true, which uses `a2enconf` to enable the config. If false, the config will be disabled with `a2disconf`.\n\n### Examples:\n\nEnable the example config.\n\n```ruby\n apache_config 'example' do\n enable true\n end\n```\n\nDisable a module:\n\n```ruby\n apache_config 'disabled_example' do\n enable false\n end\n```\n\nSee the recipes directory for many more examples of `apache_config`.\n\n\napache\\_module\n--------------\n\nEnable or disable an Apache module in\n`#{node['apache']['dir']}/mods-available` by calling `a2enmod` or\n`a2dismod` to manage the symbolic link in\n`#{node['apache']['dir']}/mods-enabled`. If the module has a\nconfiguration file, a template should be created in the cookbook where\nthe definition is used. See __Examples__.\n\n### Parameters:\n\n* `name` - Name of the module enabled or disabled with the `a2enmod` or `a2dismod` scripts.\n* `identifier` - String to identify the module for the `LoadModule` directive. Not typically needed, defaults to `#{name}_module`\n* `enable` - Default true, which uses `a2enmod` to enable the module. If false, the module will be disabled with `a2dismod`.\n* `conf` - Default false. Set to true if the module has a config file, which will use `apache_mod` for the file.\n* `filename` - specify the full name of the file, e.g.\n\n### Examples:\n\nEnable the ssl module, which also has a configuration template in `templates/default/mods/ssl.conf.erb`.\n\n```ruby\n apache_module \"ssl\" do\n conf true\n end\n```\n\nEnable the php5 module, which has a different filename than the module default:\n\n```ruby\n apache_module \"php5\" do\n filename \"libphp5.so\"\n end\n```\n\nDisable a module:\n\n```ruby\n apache_module \"disabled_module\" do\n enable false\n end\n```\n\nSee the recipes directory for many more examples of `apache_module`.\n\napache\\_mod (internal)\n----------------------\n\nSets up configuration file for an Apache module from a template. The\ntemplate should be in the same cookbook where the definition is used.\nThis is used by the `apache_module` definition and is not often used\ndirectly.\n\nThis will use a template resource to write the module's configuration\nfile in the `mods-available` under the Apache configuration directory\n(`node['apache']['dir']`). This is a platform-dependent location. See\n__apache\\_module__.\n\n### Parameters:\n\n* `name` - Name of the template. When used from the `apache_module`,\n it will use the same name as the module.\n\n### Examples:\n\nCreate `#{node['apache']['dir']}/mods-available/alias.conf`.\n\n```ruby\n apache_mod \"alias\"\n```\n\napache\\_site\n------------\n\nEnable or disable a VirtualHost in\n`#{node['apache']['dir']}/sites-available` by calling a2ensite or\na2dissite to manage the symbolic link in\n`#{node['apache']['dir']}/sites-enabled`.\n\nThe template for the site must be managed as a separate resource. To\ncombine the template with enabling a site, see `web_app`.\n\n### Parameters:\n\n* `name` - Name of the site.\n* `enable` - Default true, which uses `a2ensite` to enable the site. If false, the site will be disabled with `a2dissite`.\n\nweb\\_app\n--------\n\nManage a template resource for a VirtualHost site, and enable it with\n`apache_site`. This is commonly done for managing web applications\nsuch as Ruby on Rails, PHP or Django, and the default behavior\nreflects that. However it is flexible.\n\nThis definition includes some recipes to make sure the system is\nconfigured to have Apache and some sane default modules:\n\n* `apache2`\n* `apache2::mod_rewrite`\n* `apache2::mod_deflate`\n* `apache2::mod_headers`\n\nIt will then configure the template (see __Parameters__ and\n__Examples__ below), and enable or disable the site per the `enable`\nparameter.\n\n### Parameters:\n\nCurrent parameters used by the definition:\n\n* `name` - The name of the site. The template will be written to\n `#{node['apache']['dir']}/sites-available/#{params['name']}.conf`\n* `cookbook` - Optional. Cookbook where the source template is. If\n this is not defined, Chef will use the named template in the\n cookbook where the definition is used.\n* `template` - Default `web_app.conf.erb`, source template file.\n* `enable` - Default true. Passed to the `apache_site` definition.\n\nAdditional parameters can be defined when the definition is called in\na recipe, see __Examples__.\n\n### Examples:\n\nThe recommended way to use the `web_app` definition is in a application specific cookbook named \"my_app\".\nThe following example would look for a template named 'web_app.conf.erb' in your cookbook containing\nthe apache httpd directives defining the `VirtualHost` that would serve up \"my_app\".\n\n```ruby\n web_app \"my_app\" do\n template 'web_app.conf.erb'\n server_name node['my_app']['hostname']\n end\n```\n\nAll parameters are passed into the template. You can use whatever you\nlike. The apache2 cookbook comes with a `web_app.conf.erb` template as\nan example. The following parameters are used in the template:\n\n* `server_name` - ServerName directive.\n* `server_aliases` - ServerAlias directive. Must be an array of aliases.\n* `docroot` - DocumentRoot directive.\n* `application_name` - Used in RewriteLog directive. Will be set to the `name` parameter.\n* `directory_index` - Allow overriding the default DirectoryIndex setting, optional\n* `directory_options` - Override Options on the docroot, for example to add parameters like Includes or Indexes, optional.\n* `allow_override` - Modify the AllowOverride directive on the docroot to support apps that need .htaccess to modify configuration or require authentication.\n\nTo use the default web_app, for example:\n\n```ruby\n web_app \"my_site\" do\n server_name node['hostname']\n server_aliases [node['fqdn'], \"my-site.example.com\"]\n docroot \"/srv/www/my_site\"\n cookbook 'apache2'\n end\n```\n\nThe parameters specified will be used as:\n\n* `@params[:server_name]`\n* `@params[:server_aliases]`\n* `@params[:docroot]`\n\nIn the template. When you write your own, the `@` is significant.\n\nFor more information about Definitions and parameters, see the\n[Chef Wiki](http://docs.chef.io/definitions.html)\n\nTests\n=====\n\nThis cookbook in the [source repository](https://github.com/sous-chefs/apache2/)\ncontains chefspec, serverspec tests.\n\nPlease see the CONTRIBUTING file for information on how to add tests\nfor your contributions.\n\n\nLicense and Authors\n===================\n\n* Author:: Adam Jacob \n* Author:: Joshua Timberman \n* Author:: Bryan McLellan \n* Author:: Dave Esposito \n* Author:: David Abdemoulaie \n* Author:: Edmund Haselwanter \n* Author:: Eric Rochester \n* Author:: Jim Browne \n* Author:: Matthew Kent \n* Author:: Nathen Harvey \n* Author:: Ringo De Smet \n* Author:: Sean OMeara \n* Author:: Seth Chisamore \n* Author:: Gilles Devaux \n* Author:: Sander van Zoest \n* Author:: Taylor Price \n* Author:: Ben Dean \n\n* Copyright:: 2009-2012, Chef Software, Inc\n* Copyright:: 2011, Atriso\n* Copyright:: 2011, CustomInk, LLC.\n* Copyright:: 2013-2014, OneHealth Solutions, Inc.\n* Copyright:: 2014, Viverae, Inc.\n* Copyright:: 2015-2016, Alexander van Zoest\n* Copyright:: 2015, Ontario Systems, LLC\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n","maintainer":"Sous Chefs","maintainer_email":"help@sous-chefs.org","license":"Apache 2.0","platforms":{"debian":">= 0.0.0","ubuntu":">= 0.0.0","redhat":">= 0.0.0","centos":">= 0.0.0","fedora":">= 0.0.0","amazon":">= 0.0.0","scientific":">= 0.0.0","freebsd":">= 0.0.0","suse":">= 0.0.0","opensuse":">= 0.0.0","opensuseleap":">= 0.0.0","arch":">= 0.0.0"},"dependencies":{},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{},"source_url":"https://github.com/sous-chefs/apache2","issues_url":"https://github.com/sous-chefs/apache2/issues","chef_version":[[">= 11"]],"ohai_version":[]} \ No newline at end of file diff --git a/cookbooks/apache2/recipes/default.rb b/cookbooks/apache2/recipes/default.rb index 697577b..7f39842 100644 --- a/cookbooks/apache2/recipes/default.rb +++ b/cookbooks/apache2/recipes/default.rb @@ -1,9 +1,9 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: default # -# Copyright 2008-2013, Chef Software, Inc. -# Copyright 2014-2015, Alexander van Zoest +# Copyright:: 2008-2013, Chef Software, Inc. +# Copyright:: 2014-2015, Alexander van Zoest # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -18,8 +18,9 @@ # limitations under the License. # -package 'apache2' do +package 'apache2' do # ~FC009 only available in apt_package. See #388 package_name node['apache']['package'] + default_release node['apache']['default_release'] unless node['apache']['default_release'].nil? end %w(sites-available sites-enabled mods-available mods-enabled conf-available conf-enabled).each do |dir| @@ -43,18 +44,16 @@ end end end -directory "#{node['apache']['dir']}/conf.d" do - action :delete - recursive true -end - directory node['apache']['log_dir'] do mode '0755' + recursive true end # perl is needed for the a2* scripts package node['apache']['perl_pkg'] +package 'perl-Getopt-Long-Descriptive' if platform?('fedora') + %w(a2ensite a2dissite a2enmod a2dismod a2enconf a2disconf).each do |modscript| link "/usr/sbin/#{modscript}" do action :delete @@ -82,9 +81,6 @@ unless platform_family?('debian') command "/usr/local/bin/apache2_module_conf_generate.pl #{node['apache']['lib_dir']} #{node['apache']['dir']}/mods-available" action :nothing end - - # enable mod_deflate for consistency across distributions - include_recipe 'apache2::mod_deflate' end if platform_family?('freebsd') @@ -128,7 +124,7 @@ end directory node['apache']['lock_dir'] do mode '0755' - if node['platform_family'] == 'debian' && node['apache']['version'] == '2.2' + if node['platform_family'] == 'debian' owner node['apache']['user'] else owner 'root' @@ -143,7 +139,7 @@ template "/etc/sysconfig/#{node['apache']['package']}" do group node['apache']['root_group'] mode '0644' notifies :restart, 'service[apache2]', :delayed - only_if { platform_family?('rhel', 'fedora', 'suse') } + only_if { platform_family?('rhel', 'amazon', 'fedora', 'suse') } end template "#{node['apache']['dir']}/envvars" do @@ -156,7 +152,7 @@ template "#{node['apache']['dir']}/envvars" do end template 'apache2.conf' do - if platform_family?('rhel', 'fedora', 'arch', 'freebsd') + if platform_family?('rhel', 'amazon', 'fedora', 'arch', 'freebsd') path "#{node['apache']['conf_dir']}/httpd.conf" elsif platform_family?('debian') path "#{node['apache']['conf_dir']}/apache2.conf" @@ -182,8 +178,7 @@ apache_conf 'ports' do conf_path node['apache']['dir'] end -if node['apache']['version'] == '2.4' && !platform_family?('freebsd') - # on freebsd the prefork mpm is staticly compiled in +if node['apache']['version'] == '2.4' if node['apache']['mpm_support'].include?(node['apache']['mpm']) include_recipe "apache2::mpm_#{node['apache']['mpm']}" else @@ -203,18 +198,22 @@ if node['apache']['default_site_enabled'] end end +apache_service_name = node['apache']['service_name'] + service 'apache2' do - service_name node['apache']['service_name'] + service_name apache_service_name case node['platform_family'] when 'rhel' - restart_command '/sbin/service httpd restart && sleep 1' if node['apache']['version'] == '2.2' - reload_command '/sbin/service httpd graceful' + if node['platform_version'].to_f < 7.0 && node['apache']['version'] != '2.4' + restart_command "/sbin/service #{apache_service_name} restart && sleep 1" + reload_command "/sbin/service #{apache_service_name} graceful && sleep 1" + end when 'debian' provider Chef::Provider::Service::Debian when 'arch' - service_name 'httpd' + service_name apache_service_name end supports [:start, :restart, :reload, :status] action [:enable, :start] - only_if "#{node['apache']['binary']} -t", :environment => { 'APACHE_LOG_DIR' => node['apache']['log_dir'] }, :timeout => 10 + only_if "#{node['apache']['binary']} -t", environment: { 'APACHE_LOG_DIR' => node['apache']['log_dir'] }, timeout: 10 end diff --git a/cookbooks/apache2/recipes/mod_access_compat.rb b/cookbooks/apache2/recipes/mod_access_compat.rb index bfb6eed..6bd2e4a 100644 --- a/cookbooks/apache2/recipes/mod_access_compat.rb +++ b/cookbooks/apache2/recipes/mod_access_compat.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_access_compat # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_actions.rb b/cookbooks/apache2/recipes/mod_actions.rb index 98b8f41..d33df83 100644 --- a/cookbooks/apache2/recipes/mod_actions.rb +++ b/cookbooks/apache2/recipes/mod_actions.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_actions # -# Copyright 2008-2013, Chef Software, Inc. +# Copyright:: 2008-2013, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_alias.rb b/cookbooks/apache2/recipes/mod_alias.rb index 60ac195..6ff5f18 100644 --- a/cookbooks/apache2/recipes/mod_alias.rb +++ b/cookbooks/apache2/recipes/mod_alias.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_alias # -# Copyright 2008-2013, Chef Software, Inc. +# Copyright:: 2008-2013, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_allowmethods.rb b/cookbooks/apache2/recipes/mod_allowmethods.rb index 12f9fde..f182b69 100644 --- a/cookbooks/apache2/recipes/mod_allowmethods.rb +++ b/cookbooks/apache2/recipes/mod_allowmethods.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_allowmethods # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_apreq2.rb b/cookbooks/apache2/recipes/mod_apreq2.rb index 005c72c..57e8057 100644 --- a/cookbooks/apache2/recipes/mod_apreq2.rb +++ b/cookbooks/apache2/recipes/mod_apreq2.rb @@ -1,10 +1,10 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: apreq2 # # modified from the python recipe by Jeremy Bingham # -# Copyright 2008-2013, Chef Software, Inc. +# Copyright:: 2008-2013, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -28,7 +28,7 @@ when 'suse' package 'apache2-mod_apreq2' do notifies :run, 'execute[generate-module-list]', :immediately end -when 'rhel', 'fedora' +when 'rhel', 'fedora', 'amazon' package 'libapreq2' do notifies :run, 'execute[generate-module-list]', :immediately end @@ -43,8 +43,8 @@ when 'rhel', 'fedora' end file "#{node['apache']['dir']}/conf.d/apreq.conf" do - action :delete - backup false + content '# conf is under mods-available/apreq.conf - apache2 cookbook\n' + only_if { ::Dir.exist?("#{node['apache']['dir']}/conf.d") } end apache_module 'apreq' diff --git a/cookbooks/apache2/recipes/mod_asis.rb b/cookbooks/apache2/recipes/mod_asis.rb index bba792e..63502a9 100644 --- a/cookbooks/apache2/recipes/mod_asis.rb +++ b/cookbooks/apache2/recipes/mod_asis.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_asis # -# Copyright 2008-2009, Chef Software, Inc. +# Copyright:: 2008-2009, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_auth_basic.rb b/cookbooks/apache2/recipes/mod_auth_basic.rb index 8906a25..ac6c8be 100644 --- a/cookbooks/apache2/recipes/mod_auth_basic.rb +++ b/cookbooks/apache2/recipes/mod_auth_basic.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_auth_basic # -# Copyright 2008-2013, Chef Software, Inc. +# Copyright:: 2008-2013, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_auth_cas.rb b/cookbooks/apache2/recipes/mod_auth_cas.rb index 45c9058..ff0e61e 100644 --- a/cookbooks/apache2/recipes/mod_auth_cas.rb +++ b/cookbooks/apache2/recipes/mod_auth_cas.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_auth_cas # -# Copyright 2013, Chef Software, Inc. +# Copyright:: 2013, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -45,14 +45,14 @@ else when 'debian' package 'libapache2-mod-auth-cas' - when 'rhel', 'fedora' + when 'rhel', 'fedora', 'amazon' yum_package 'mod_auth_cas' do notifies :run, 'execute[generate-module-list]', :immediately end file "#{node['apache']['dir']}/conf.d/auth_cas.conf" do - action :delete - backup false + content '# conf is under mods-available/auth_cas.conf - apache2 cookbook\n' + only_if { ::Dir.exist?("#{node['apache']['dir']}/conf.d") } end end end diff --git a/cookbooks/apache2/recipes/mod_auth_digest.rb b/cookbooks/apache2/recipes/mod_auth_digest.rb index ca2e094..5c87167 100644 --- a/cookbooks/apache2/recipes/mod_auth_digest.rb +++ b/cookbooks/apache2/recipes/mod_auth_digest.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_auth_digest # -# Copyright 2008-2013, Chef Software, Inc. +# Copyright:: 2008-2013, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_auth_form.rb b/cookbooks/apache2/recipes/mod_auth_form.rb index b6bfc88..8ddddd3 100644 --- a/cookbooks/apache2/recipes/mod_auth_form.rb +++ b/cookbooks/apache2/recipes/mod_auth_form.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_auth_form # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_auth_openid.rb b/cookbooks/apache2/recipes/mod_auth_openid.rb index 280fba4..193fbb8 100644 --- a/cookbooks/apache2/recipes/mod_auth_openid.rb +++ b/cookbooks/apache2/recipes/mod_auth_openid.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_auth_openid # -# Copyright 2008-2013, Chef Software, Inc. +# Copyright:: 2008-2013, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -20,7 +20,7 @@ openid_dev_pkgs = value_for_platform_family( 'debian' => %W(automake make g++ #{node['apache']['devel_package']} libopkele-dev libopkele3 libtool), 'suse' => %W(automake make g++ #{node['apache']['devel_package']} libopkele-dev libopkele3 libtool), - %w(rhel fedora) => %W(gcc-c++ #{node['apache']['devel_package']} curl-devel libtidy libtidy-devel sqlite-devel pcre-devel openssl-devel make libtool), + %w(rhel fedora amazon) => %W(gcc-c++ #{node['apache']['devel_package']} curl-devel libtidy libtidy-devel sqlite-devel pcre-devel openssl-devel make libtool), 'arch' => %w(libopkele), 'freebsd' => %w(libopkele pcre sqlite3) ) @@ -44,7 +44,7 @@ else end case node['platform_family'] -when 'rhel', 'fedora' +when 'rhel', 'fedora', 'amazon' remote_file "#{Chef::Config['file_cache_path']}/libopkele-2.0.4.tar.gz" do source 'http://kin.klever.net/dist/libopkele-2.0.4.tar.gz' mode '0644' diff --git a/cookbooks/apache2/recipes/mod_authn_anon.rb b/cookbooks/apache2/recipes/mod_authn_anon.rb index 21750f5..d767e9f 100644 --- a/cookbooks/apache2/recipes/mod_authn_anon.rb +++ b/cookbooks/apache2/recipes/mod_authn_anon.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_authn_anon # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_authn_core.rb b/cookbooks/apache2/recipes/mod_authn_core.rb index 8b4097b..c7b826e 100644 --- a/cookbooks/apache2/recipes/mod_authn_core.rb +++ b/cookbooks/apache2/recipes/mod_authn_core.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_authn_core # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_authn_dbd.rb b/cookbooks/apache2/recipes/mod_authn_dbd.rb index 281c702..68edb8f 100644 --- a/cookbooks/apache2/recipes/mod_authn_dbd.rb +++ b/cookbooks/apache2/recipes/mod_authn_dbd.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_authn_dbd # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_authn_dbm.rb b/cookbooks/apache2/recipes/mod_authn_dbm.rb index e4c30ff..418dafb 100644 --- a/cookbooks/apache2/recipes/mod_authn_dbm.rb +++ b/cookbooks/apache2/recipes/mod_authn_dbm.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_authn_dbm # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_authn_file.rb b/cookbooks/apache2/recipes/mod_authn_file.rb index 5cb0bff..46f8458 100644 --- a/cookbooks/apache2/recipes/mod_authn_file.rb +++ b/cookbooks/apache2/recipes/mod_authn_file.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_authn_file # -# Copyright 2008-2013, Chef Software, Inc. +# Copyright:: 2008-2013, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_authn_socache.rb b/cookbooks/apache2/recipes/mod_authn_socache.rb index 9f1c5fe..148be8e 100644 --- a/cookbooks/apache2/recipes/mod_authn_socache.rb +++ b/cookbooks/apache2/recipes/mod_authn_socache.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_authn_socache # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/chef_handler/attributes/default.rb b/cookbooks/apache2/recipes/mod_authnz_fcgi.rb similarity index 67% rename from cookbooks/chef_handler/attributes/default.rb rename to cookbooks/apache2/recipes/mod_authnz_fcgi.rb index 1a97bcd..fba9ca9 100644 --- a/cookbooks/chef_handler/attributes/default.rb +++ b/cookbooks/apache2/recipes/mod_authnz_fcgi.rb @@ -1,9 +1,8 @@ # -# Author:: Seth Chisamore () -# Cookbook Name:: chef_handler -# Attributes:: default +# Cookbook:: apache2 +# Recipe:: mod_authnz_fcgi # -# Copyright 2011-2016, Chef Software, Inc +# Copyright:: 2016, Alexander van Zoest # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -18,4 +17,4 @@ # limitations under the License. # -default['chef_handler']['handler_path'] = "#{File.expand_path(File.join(Chef::Config[:file_cache_path], '..'))}/handlers" +apache_module 'authnz_fcgi' diff --git a/cookbooks/apache2/recipes/mod_authnz_ldap.rb b/cookbooks/apache2/recipes/mod_authnz_ldap.rb index 1c7f3ea..53ca785 100644 --- a/cookbooks/apache2/recipes/mod_authnz_ldap.rb +++ b/cookbooks/apache2/recipes/mod_authnz_ldap.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_authnz_ldap # -# Copyright 2008-2013, Chef Software, Inc. +# Copyright:: 2008-2013, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_authz_core.rb b/cookbooks/apache2/recipes/mod_authz_core.rb index af58f1a..97529fb 100644 --- a/cookbooks/apache2/recipes/mod_authz_core.rb +++ b/cookbooks/apache2/recipes/mod_authz_core.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_authz_core # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_authz_dbd.rb b/cookbooks/apache2/recipes/mod_authz_dbd.rb index 290e5d9..4d114b5 100644 --- a/cookbooks/apache2/recipes/mod_authz_dbd.rb +++ b/cookbooks/apache2/recipes/mod_authz_dbd.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_authz_dbd # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_authz_dbm.rb b/cookbooks/apache2/recipes/mod_authz_dbm.rb index 0b3ee9b..7d900f1 100644 --- a/cookbooks/apache2/recipes/mod_authz_dbm.rb +++ b/cookbooks/apache2/recipes/mod_authz_dbm.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_authz_dbm # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_authz_default.rb b/cookbooks/apache2/recipes/mod_authz_default.rb index 7a551a0..4973fdf 100644 --- a/cookbooks/apache2/recipes/mod_authz_default.rb +++ b/cookbooks/apache2/recipes/mod_authz_default.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_authz_default # -# Copyright 2013, Chef Software, Inc. +# Copyright:: 2013, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_authz_groupfile.rb b/cookbooks/apache2/recipes/mod_authz_groupfile.rb index f035838..1df8ad0 100644 --- a/cookbooks/apache2/recipes/mod_authz_groupfile.rb +++ b/cookbooks/apache2/recipes/mod_authz_groupfile.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_authz_groupfile # -# Copyright 2008-2013, Chef Software, Inc. +# Copyright:: 2008-2013, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_authz_host.rb b/cookbooks/apache2/recipes/mod_authz_host.rb index e388190..202fd08 100644 --- a/cookbooks/apache2/recipes/mod_authz_host.rb +++ b/cookbooks/apache2/recipes/mod_authz_host.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_authz_host # -# Copyright 2008-2013, Chef Software, Inc. +# Copyright:: 2008-2013, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_authz_owner.rb b/cookbooks/apache2/recipes/mod_authz_owner.rb index 4123fc8..e1a958d 100644 --- a/cookbooks/apache2/recipes/mod_authz_owner.rb +++ b/cookbooks/apache2/recipes/mod_authz_owner.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_authz_owner # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_authz_user.rb b/cookbooks/apache2/recipes/mod_authz_user.rb index e646ed4..03d1b16 100644 --- a/cookbooks/apache2/recipes/mod_authz_user.rb +++ b/cookbooks/apache2/recipes/mod_authz_user.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_authz_user # -# Copyright 2008-2013, Chef Software, Inc. +# Copyright:: 2008-2013, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_autoindex.rb b/cookbooks/apache2/recipes/mod_autoindex.rb index da2f6a6..2b0f4f2 100644 --- a/cookbooks/apache2/recipes/mod_autoindex.rb +++ b/cookbooks/apache2/recipes/mod_autoindex.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_autoindex # -# Copyright 2008-2013, Chef Software, Inc. +# Copyright:: 2008-2013, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_buffer.rb b/cookbooks/apache2/recipes/mod_buffer.rb index 939f7d9..8df551e 100644 --- a/cookbooks/apache2/recipes/mod_buffer.rb +++ b/cookbooks/apache2/recipes/mod_buffer.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_buffer # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_cache.rb b/cookbooks/apache2/recipes/mod_cache.rb index 9ce0cb9..4eb7c90 100644 --- a/cookbooks/apache2/recipes/mod_cache.rb +++ b/cookbooks/apache2/recipes/mod_cache.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_cache # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_cache_disk.rb b/cookbooks/apache2/recipes/mod_cache_disk.rb index a26d13e..be53224 100644 --- a/cookbooks/apache2/recipes/mod_cache_disk.rb +++ b/cookbooks/apache2/recipes/mod_cache_disk.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_cache_disk # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_cache_socache.rb b/cookbooks/apache2/recipes/mod_cache_socache.rb index 110b0f8..b2fa8ca 100644 --- a/cookbooks/apache2/recipes/mod_cache_socache.rb +++ b/cookbooks/apache2/recipes/mod_cache_socache.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_cache_socache # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/attributes/mod_php5.rb b/cookbooks/apache2/recipes/mod_cern_meta.rb similarity index 61% rename from cookbooks/apache2/attributes/mod_php5.rb rename to cookbooks/apache2/recipes/mod_cern_meta.rb index 06aea8b..be6018e 100644 --- a/cookbooks/apache2/attributes/mod_php5.rb +++ b/cookbooks/apache2/recipes/mod_cern_meta.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 -# Attributes:: mod_php5 +# Cookbook:: apache2 +# Recipe:: mod_cern_meta # -# Copyright 2014, Viverae, Inc. +# Copyright:: 2016, Alexander van Zoest # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,10 +15,6 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +# -default['apache']['mod_php5']['install_method'] = 'package' -default['apache']['mod_php5']['so_filename'] = 'libphp5.so' - -if node['platform'] == 'amazon' && node['apache']['version'] == '2.4' - default['apache']['mod_php5']['so_filename'] = 'libphp.so' -end +apache_module 'cern_meta' diff --git a/cookbooks/apache2/recipes/mod_cgi.rb b/cookbooks/apache2/recipes/mod_cgi.rb index 7b6f8b4..bc8fac1 100644 --- a/cookbooks/apache2/recipes/mod_cgi.rb +++ b/cookbooks/apache2/recipes/mod_cgi.rb @@ -1,9 +1,9 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_cgi # -# Copyright 2008-2013, Chef Software, Inc. -# Copyright 2014, Viverae, Inc. +# Copyright:: 2008-2013, Chef Software, Inc. +# Copyright:: 2014, Viverae, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_cgid.rb b/cookbooks/apache2/recipes/mod_cgid.rb index 103f169..08dfc9d 100644 --- a/cookbooks/apache2/recipes/mod_cgid.rb +++ b/cookbooks/apache2/recipes/mod_cgid.rb @@ -1,9 +1,9 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_cgid # -# Copyright 2013, OneHealth Solutions, Inc. -# Copyright 2014, Viverae, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. +# Copyright:: 2014, Viverae, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_charset_lite.rb b/cookbooks/apache2/recipes/mod_charset_lite.rb index a1db83c..2ce46e3 100644 --- a/cookbooks/apache2/recipes/mod_charset_lite.rb +++ b/cookbooks/apache2/recipes/mod_charset_lite.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_charset_lite # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_cloudflare.rb b/cookbooks/apache2/recipes/mod_cloudflare.rb index f6ed37e..18b5e98 100644 --- a/cookbooks/apache2/recipes/mod_cloudflare.rb +++ b/cookbooks/apache2/recipes/mod_cloudflare.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_cloudflare # -# Copyright 2008-2013, Chef Software, Inc. +# Copyright:: 2008-2013, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_data.rb b/cookbooks/apache2/recipes/mod_data.rb index 6ea7c47..9ebb567 100644 --- a/cookbooks/apache2/recipes/mod_data.rb +++ b/cookbooks/apache2/recipes/mod_data.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_data # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_dav.rb b/cookbooks/apache2/recipes/mod_dav.rb index 2f4f223..f96bcaf 100644 --- a/cookbooks/apache2/recipes/mod_dav.rb +++ b/cookbooks/apache2/recipes/mod_dav.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_dav # -# Copyright 2008-2013, Chef Software, Inc. +# Copyright:: 2008-2013, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_dav_fs.rb b/cookbooks/apache2/recipes/mod_dav_fs.rb index cecd43d..0e589ff 100644 --- a/cookbooks/apache2/recipes/mod_dav_fs.rb +++ b/cookbooks/apache2/recipes/mod_dav_fs.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_dav_fs # -# Copyright 2011-2013, Atriso +# Copyright:: 2011-2013, Atriso # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_dav_lock.rb b/cookbooks/apache2/recipes/mod_dav_lock.rb index e73e708..6104743 100644 --- a/cookbooks/apache2/recipes/mod_dav_lock.rb +++ b/cookbooks/apache2/recipes/mod_dav_lock.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_dav_lock # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_dav_svn.rb b/cookbooks/apache2/recipes/mod_dav_svn.rb index 901f167..d3cfd2f 100644 --- a/cookbooks/apache2/recipes/mod_dav_svn.rb +++ b/cookbooks/apache2/recipes/mod_dav_svn.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_dav_svn # -# Copyright 2008-2009, Chef Software, Inc. +# Copyright:: 2008-2009, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -21,7 +21,7 @@ include_recipe 'apache2::mod_dav' package 'libapache2-svn' do case node['platform_family'] - when 'rhel', 'fedora', 'suse' + when 'rhel', 'fedora', 'suse', 'amazon' package_name 'mod_dav_svn' else package_name 'libapache2-svn' @@ -29,7 +29,7 @@ package 'libapache2-svn' do end case node['platform_family'] -when 'rhel', 'fedora', 'suse' +when 'rhel', 'fedora', 'suse', 'amazon' file "#{node['apache']['dir']}/conf.d/subversion.conf" do action :delete backup false diff --git a/cookbooks/apache2/recipes/mod_dbd.rb b/cookbooks/apache2/recipes/mod_dbd.rb index c5f9f4a..d496162 100644 --- a/cookbooks/apache2/recipes/mod_dbd.rb +++ b/cookbooks/apache2/recipes/mod_dbd.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_dbd # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_deflate.rb b/cookbooks/apache2/recipes/mod_deflate.rb index 9ecd619..c976d96 100644 --- a/cookbooks/apache2/recipes/mod_deflate.rb +++ b/cookbooks/apache2/recipes/mod_deflate.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_deflate # -# Copyright 2008-2013, Chef Software, Inc. +# Copyright:: 2008-2013, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_dialup.rb b/cookbooks/apache2/recipes/mod_dialup.rb index 75d271d..105f3ca 100644 --- a/cookbooks/apache2/recipes/mod_dialup.rb +++ b/cookbooks/apache2/recipes/mod_dialup.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_dialup # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_dir.rb b/cookbooks/apache2/recipes/mod_dir.rb index 86fdf9a..c9d0387 100644 --- a/cookbooks/apache2/recipes/mod_dir.rb +++ b/cookbooks/apache2/recipes/mod_dir.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_dir # -# Copyright 2008-2013, Chef Software, Inc. +# Copyright:: 2008-2013, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_dump_io.rb b/cookbooks/apache2/recipes/mod_dump_io.rb index 46015e4..5d77ed1 100644 --- a/cookbooks/apache2/recipes/mod_dump_io.rb +++ b/cookbooks/apache2/recipes/mod_dump_io.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_dump_io # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_echo.rb b/cookbooks/apache2/recipes/mod_echo.rb index b8aeb21..8770b7e 100644 --- a/cookbooks/apache2/recipes/mod_echo.rb +++ b/cookbooks/apache2/recipes/mod_echo.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_echo # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_env.rb b/cookbooks/apache2/recipes/mod_env.rb index b5b30fc..b392cc1 100644 --- a/cookbooks/apache2/recipes/mod_env.rb +++ b/cookbooks/apache2/recipes/mod_env.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_env # -# Copyright 2008-2013, Chef Software, Inc. +# Copyright:: 2008-2013, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_expires.rb b/cookbooks/apache2/recipes/mod_expires.rb index 5c475e2..23977d9 100644 --- a/cookbooks/apache2/recipes/mod_expires.rb +++ b/cookbooks/apache2/recipes/mod_expires.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_expires # -# Copyright 2008-2013, Chef Software, Inc. +# Copyright:: 2008-2013, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_ext_filter.rb b/cookbooks/apache2/recipes/mod_ext_filter.rb index c8b27bb..296b262 100644 --- a/cookbooks/apache2/recipes/mod_ext_filter.rb +++ b/cookbooks/apache2/recipes/mod_ext_filter.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_ext_filter # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_fastcgi.rb b/cookbooks/apache2/recipes/mod_fastcgi.rb index 9eb4382..e2d0759 100644 --- a/cookbooks/apache2/recipes/mod_fastcgi.rb +++ b/cookbooks/apache2/recipes/mod_fastcgi.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_fastcgi # -# Copyright 2008-2013, Chef Software, Inc. +# Copyright:: 2008-2013, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,37 +17,35 @@ # limitations under the License. # -if platform_family?('debian') - if node['apache']['mod_fastcgi']['install_method'] == 'source' +if node['apache']['mod_fastcgi']['install_method'] == 'package' + package node['apache']['mod_fastcgi']['package'] +else + if platform_family?('debian') package 'build-essential' package node['apache']['devel_package'] - else - package 'libapache2-mod-fastcgi' - end -elsif platform_family?('rhel') - %W(gcc make libtool #{node['apache']['devel_package']} apr-devel apr).each do |package| - yum_package package do - action :upgrade + elsif platform_family?('rhel', 'amazon') + %W(gcc make libtool #{node['apache']['devel_package']} apr-devel apr).each do |package| + package package do + action :upgrade + end end end -end -if platform_family?('rhel') || (platform_family?('debian') && node['apache']['mod_fastcgi']['install_method'] == 'source') - src_filepath = "#{Chef::Config['file_cache_path']}/fastcgi.tar.gz" + src_filepath = "#{Chef::Config['file_cache_path']}/fastcgi.tar.gz" remote_file 'download fastcgi source' do source node['apache']['mod_fastcgi']['download_url'] path src_filepath backup false end - if platform_family?('debian') - top_dir = node['apache']['build_dir'] - else - top_dir = node['apache']['lib_dir'] - end + top_dir = if platform_family?('debian') + node['apache']['build_dir'] + else + node['apache']['lib_dir'] + end include_recipe 'apache2::default' bash 'compile fastcgi source' do - notifies :run, 'execute[generate-module-list]', :immediately if platform_family?('rhel') + notifies :run, 'execute[generate-module-list]', :immediately if platform_family?('rhel', 'amazon') not_if "test -f #{node['apache']['dir']}/mods-available/fastcgi.conf" cwd ::File.dirname(src_filepath) code <<-EOH diff --git a/cookbooks/apache2/recipes/mod_fcgid.rb b/cookbooks/apache2/recipes/mod_fcgid.rb index ddfc52e..5283fec 100644 --- a/cookbooks/apache2/recipes/mod_fcgid.rb +++ b/cookbooks/apache2/recipes/mod_fcgid.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_fcgid # -# Copyright 2008-2013, Chef Software, Inc. +# Copyright:: 2008-2013, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -19,22 +19,34 @@ if platform_family?('debian') package 'libapache2-mod-fcgid' -elsif platform_family?('rhel', 'fedora') +elsif platform_family?('rhel', 'fedora', 'amazon') package 'mod_fcgid' do notifies :run, 'execute[generate-module-list]', :immediately end file "#{node['apache']['dir']}/conf.d/fcgid.conf" do - action :delete - backup false + content '# conf is under mods-available/fcgid.conf - apache2 cookbook\n' + only_if { ::Dir.exist?("#{node['apache']['dir']}/conf.d") } end - directory '/var/run/httpd/mod_fcgid' do - owner node['apache']['user'] - group node['apache']['group'] - recursive true - only_if { node['platform_version'].to_i >= 6 } + # CentOS 7 (and recent Fedoras) have Apache 2.4, where FCGI socket path + # and shared memory path is managed adequately without further involvment + # neccessary (subdirectory is created under /var/run/httpd). + # + # However, when the path is specified manually, that subdirectory is NOT + # created automatically if it doesn't already exist and Apache fails to + # start. Since in recent RHEL systems /var/run is on tmpfs, end result is + # that chef-created subdirectory disappears on shutdown, and Apache fails + # to start after server reboot. Best to leave out these two settings + # unset then. + if (node['platform_family'] == 'rhel') && (node['platform_version'].to_i == 6) + directory '/var/run/httpd/mod_fcgid' do + owner node['apache']['user'] + group node['apache']['group'] + recursive true + end end + elsif platform_family?('suse') apache_lib_path = node['apache']['lib_dir'] diff --git a/cookbooks/apache2/recipes/mod_file_cache.rb b/cookbooks/apache2/recipes/mod_file_cache.rb index 984554e..c1ae79b 100644 --- a/cookbooks/apache2/recipes/mod_file_cache.rb +++ b/cookbooks/apache2/recipes/mod_file_cache.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_file_cache # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_filter.rb b/cookbooks/apache2/recipes/mod_filter.rb index a9b73c5..7b6f444 100644 --- a/cookbooks/apache2/recipes/mod_filter.rb +++ b/cookbooks/apache2/recipes/mod_filter.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_filter # -# Copyright 2008-2013, Chef Software, Inc. +# Copyright:: 2008-2013, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_headers.rb b/cookbooks/apache2/recipes/mod_headers.rb index 4ca3628..a88de10 100644 --- a/cookbooks/apache2/recipes/mod_headers.rb +++ b/cookbooks/apache2/recipes/mod_headers.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_headers # -# Copyright 2008-2013, Chef Software, Inc. +# Copyright:: 2008-2013, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,4 +17,6 @@ # limitations under the License. # -apache_module 'headers' +apache_module 'headers' do + restart true +end diff --git a/cookbooks/apache2/recipes/mod_heartbeat.rb b/cookbooks/apache2/recipes/mod_heartbeat.rb index 1e7f8ca..a19d2f0 100644 --- a/cookbooks/apache2/recipes/mod_heartbeat.rb +++ b/cookbooks/apache2/recipes/mod_heartbeat.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_heartbeat # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_heartmonitor.rb b/cookbooks/apache2/recipes/mod_heartmonitor.rb index c017be2..e45f765 100644 --- a/cookbooks/apache2/recipes/mod_heartmonitor.rb +++ b/cookbooks/apache2/recipes/mod_heartmonitor.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_heartmonitor # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/chef_handler/recipes/json_file.rb b/cookbooks/apache2/recipes/mod_http2.rb similarity index 58% rename from cookbooks/chef_handler/recipes/json_file.rb rename to cookbooks/apache2/recipes/mod_http2.rb index f6e37c5..cb13c0d 100644 --- a/cookbooks/chef_handler/recipes/json_file.rb +++ b/cookbooks/apache2/recipes/mod_http2.rb @@ -1,9 +1,8 @@ # -# Author:: Seth Chisamore () -# Cookbook Name:: chef_handler -# Recipe:: json_file +# Cookbook:: apache2 +# Recipe:: mod_http2 # -# Copyright 2011-2016, Chef Software, Inc. +# Copyright:: 2016, Alexander van Zoest # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -18,11 +17,4 @@ # limitations under the License. # -# force resource actions in compile phase so exception handler -# fires for compile phase exceptions - -chef_handler 'Chef::Handler::JsonFile' do - source 'chef/handler/json_file' - arguments path: '/var/chef/reports' - action :nothing -end.run_action(:enable) +apache_module 'http2' diff --git a/cookbooks/chef_handler/recipes/default.rb b/cookbooks/apache2/recipes/mod_ident.rb similarity index 54% rename from cookbooks/chef_handler/recipes/default.rb rename to cookbooks/apache2/recipes/mod_ident.rb index 3761c41..ce5cade 100644 --- a/cookbooks/chef_handler/recipes/default.rb +++ b/cookbooks/apache2/recipes/mod_ident.rb @@ -1,9 +1,8 @@ # -# Author:: Seth Chisamore () -# Cookbook Name:: chef_handler -# Recipe:: default +# Cookbook:: apache2 +# Recipe:: mod_ident # -# Copyright 2011-2016, Chef Software, Inc. +# Copyright:: 2016, Alexander van Zoest # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -18,15 +17,4 @@ # limitations under the License. # -Chef::Log.info("Chef Handlers will be located at: #{node['chef_handler']['handler_path']}") - -remote_directory node['chef_handler']['handler_path'] do - source 'handlers' - unless platform?('windows') - owner 'root' - mode '0755' - recursive true - end - group node['root_group'] - action :nothing -end.run_action(:create) +apache_module 'ident' diff --git a/cookbooks/apache2/recipes/mod_include.rb b/cookbooks/apache2/recipes/mod_include.rb index ffe57a1..679f04f 100644 --- a/cookbooks/apache2/recipes/mod_include.rb +++ b/cookbooks/apache2/recipes/mod_include.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_include # -# Copyright 2012-2013, Chef Software, Inc. +# Copyright:: 2012-2013, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_info.rb b/cookbooks/apache2/recipes/mod_info.rb index c30f704..46932b3 100644 --- a/cookbooks/apache2/recipes/mod_info.rb +++ b/cookbooks/apache2/recipes/mod_info.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_info # -# Copyright 2013, Chef Software, Inc. +# Copyright:: 2013, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_jk.rb b/cookbooks/apache2/recipes/mod_jk.rb index 5d468c5..9d9fca7 100644 --- a/cookbooks/apache2/recipes/mod_jk.rb +++ b/cookbooks/apache2/recipes/mod_jk.rb @@ -1,9 +1,9 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: jk # -# Copyright 2013, Mike Babineau -# Copyright 2013, Chef Software, Inc. +# Copyright:: 2013, Mike Babineau +# Copyright:: 2013, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -20,7 +20,7 @@ package 'libapache2-mod-jk' do case node['platform_family'] - when 'rhel', 'fedora', 'suse' + when 'rhel', 'fedora', 'suse', 'amazon' package_name 'mod_jk' else package_name 'libapache2-mod-jk' diff --git a/cookbooks/apache2/recipes/mod_lbmethod_bybusyness.rb b/cookbooks/apache2/recipes/mod_lbmethod_bybusyness.rb index ebb1b2f..3398583 100644 --- a/cookbooks/apache2/recipes/mod_lbmethod_bybusyness.rb +++ b/cookbooks/apache2/recipes/mod_lbmethod_bybusyness.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_lbmethod_bybusyness # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_lbmethod_byrequests.rb b/cookbooks/apache2/recipes/mod_lbmethod_byrequests.rb index caa4778..43e910d 100644 --- a/cookbooks/apache2/recipes/mod_lbmethod_byrequests.rb +++ b/cookbooks/apache2/recipes/mod_lbmethod_byrequests.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_lbmethod_byrequests # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_lbmethod_bytraffic.rb b/cookbooks/apache2/recipes/mod_lbmethod_bytraffic.rb index 0960078..1faf84f 100644 --- a/cookbooks/apache2/recipes/mod_lbmethod_bytraffic.rb +++ b/cookbooks/apache2/recipes/mod_lbmethod_bytraffic.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_lbmethod_bytraffic # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_lbmethod_heartbeat.rb b/cookbooks/apache2/recipes/mod_lbmethod_heartbeat.rb index 0d8064a..a79b738 100644 --- a/cookbooks/apache2/recipes/mod_lbmethod_heartbeat.rb +++ b/cookbooks/apache2/recipes/mod_lbmethod_heartbeat.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_lbmethod_heartbeat # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_ldap.rb b/cookbooks/apache2/recipes/mod_ldap.rb index 2425f5d..612b17f 100644 --- a/cookbooks/apache2/recipes/mod_ldap.rb +++ b/cookbooks/apache2/recipes/mod_ldap.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_ldap # -# Copyright 2008-2013, Chef Software, Inc. +# Copyright:: 2008-2013, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,6 +17,10 @@ # limitations under the License. # +if platform_family?('rhel', 'amazon') && node['apache']['version'] == '2.4' + package 'mod_ldap' +end + apache_module 'ldap' do conf true end diff --git a/cookbooks/apache2/recipes/mod_log_config.rb b/cookbooks/apache2/recipes/mod_log_config.rb index 2f7633e..1817387 100644 --- a/cookbooks/apache2/recipes/mod_log_config.rb +++ b/cookbooks/apache2/recipes/mod_log_config.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_log_config # -# Copyright 2008-2013, Chef Software, Inc. +# Copyright:: 2008-2013, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,7 +17,7 @@ # limitations under the License. # -if platform_family?('rhel', 'fedora', 'suse', 'arch', 'freebsd') +if platform_family?('rhel', 'fedora', 'suse', 'arch', 'freebsd', 'amazon') apache_module 'log_config' else include_recipe 'apache2::default' diff --git a/cookbooks/apache2/recipes/mod_log_debug.rb b/cookbooks/apache2/recipes/mod_log_debug.rb index 17ee6c4..9615b41 100644 --- a/cookbooks/apache2/recipes/mod_log_debug.rb +++ b/cookbooks/apache2/recipes/mod_log_debug.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_log_debug # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_log_forensic.rb b/cookbooks/apache2/recipes/mod_log_forensic.rb index 61370e2..c9dabb4 100644 --- a/cookbooks/apache2/recipes/mod_log_forensic.rb +++ b/cookbooks/apache2/recipes/mod_log_forensic.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_log_forensic # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_logio.rb b/cookbooks/apache2/recipes/mod_logio.rb index ca7a6dc..5bce35e 100644 --- a/cookbooks/apache2/recipes/mod_logio.rb +++ b/cookbooks/apache2/recipes/mod_logio.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_logio # -# Copyright 2008-2013, Chef Software, Inc. +# Copyright:: 2008-2013, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,7 +17,7 @@ # limitations under the License. # -if platform_family?('rhel', 'fedora', 'suse', 'arch', 'freebsd') +if platform_family?('rhel', 'fedora', 'suse', 'arch', 'freebsd', 'amazon') apache_module 'logio' else include_recipe 'apache2::default' diff --git a/cookbooks/apache2/recipes/mod_lua.rb b/cookbooks/apache2/recipes/mod_lua.rb index 6065c79..b6855f6 100644 --- a/cookbooks/apache2/recipes/mod_lua.rb +++ b/cookbooks/apache2/recipes/mod_lua.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_lua # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_macro.rb b/cookbooks/apache2/recipes/mod_macro.rb index 88563c9..1fe377a 100644 --- a/cookbooks/apache2/recipes/mod_macro.rb +++ b/cookbooks/apache2/recipes/mod_macro.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_macro # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_mime.rb b/cookbooks/apache2/recipes/mod_mime.rb index 45d840e..890dcec 100644 --- a/cookbooks/apache2/recipes/mod_mime.rb +++ b/cookbooks/apache2/recipes/mod_mime.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_mime # -# Copyright 2008-2013, Chef Software, Inc. +# Copyright:: 2008-2013, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_mime_magic.rb b/cookbooks/apache2/recipes/mod_mime_magic.rb index 751d1dd..5fb23cb 100644 --- a/cookbooks/apache2/recipes/mod_mime_magic.rb +++ b/cookbooks/apache2/recipes/mod_mime_magic.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_mime_magic # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_negotiation.rb b/cookbooks/apache2/recipes/mod_negotiation.rb index 60aba01..ba26f89 100644 --- a/cookbooks/apache2/recipes/mod_negotiation.rb +++ b/cookbooks/apache2/recipes/mod_negotiation.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_negotiation # -# Copyright 2008-2013, Chef Software, Inc. +# Copyright:: 2008-2013, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_pagespeed.rb b/cookbooks/apache2/recipes/mod_pagespeed.rb index f479d68..5e7bb72 100644 --- a/cookbooks/apache2/recipes/mod_pagespeed.rb +++ b/cookbooks/apache2/recipes/mod_pagespeed.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_pagespeed # -# Copyright 2013, ZOZI +# Copyright:: 2013, ZOZI # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_perl.rb b/cookbooks/apache2/recipes/mod_perl.rb index 1200712..f2c8027 100644 --- a/cookbooks/apache2/recipes/mod_perl.rb +++ b/cookbooks/apache2/recipes/mod_perl.rb @@ -1,10 +1,10 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_perl # # adapted from the mod_python recipe by Jeremy Bingham # -# Copyright 2008-2013, Chef Software, Inc. +# Copyright:: 2008-2013, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -21,16 +21,22 @@ case node['platform_family'] when 'debian' - %w(libapache2-mod-perl2 libapache2-request-perl apache2-mpm-prefork).each do |pkg| + %w(libapache2-mod-perl2 libapache2-request-perl).each do |pkg| package pkg end + if node['platform'] == 'ubuntu' && node['platform_version'].to_f <= 14.04 + package 'apache2-mpm-prefork' + end + if node['platform'] == 'debian' && node['platform_version'].to_f <= 8 + package 'apache2-mpm-prefork' + end when 'suse' package 'apache2-mod_perl' do notifies :run, 'execute[generate-module-list]', :immediately end package 'perl-Apache2-Request' -when 'rhel', 'fedora' +when 'rhel', 'fedora', 'amazon' package 'mod_perl' do notifies :run, 'execute[generate-module-list]', :immediately end @@ -46,8 +52,8 @@ when 'freebsd' end file "#{node['apache']['dir']}/conf.d/perl.conf" do - action :delete - backup false + content '# conf is under mods-available/perl.conf - apache2 cookbook\n' + only_if { ::Dir.exist?("#{node['apache']['dir']}/conf.d") } end apache_module 'perl' diff --git a/cookbooks/apache2/recipes/mod_php.rb b/cookbooks/apache2/recipes/mod_php.rb new file mode 100644 index 0000000..20b10f2 --- /dev/null +++ b/cookbooks/apache2/recipes/mod_php.rb @@ -0,0 +1,101 @@ +# +# Cookbook:: apache2 +# Recipe:: mod_php5 +# +# Copyright:: 2008-2013, Chef Software, Inc. +# Copyright:: 2014, OneHealth Solutions, Inc. +# Copyright:: 2014, Viverae, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +if node['apache']['mpm'] != 'prefork' + Chef::Log.warn('apache2::mod_php generally is expected to be run under a non-threaded MPM, such as prefork') + Chef::Log.warn('See http://php.net/manual/en/faq.installation.php#faq.installation.apache2') + Chef::Log.warn("Currently the apache2 cookbook is configured to use the '#{node['apache']['mpm']}' MPM") +end + +case node['platform_family'] +when 'debian' + if node['platform'] == 'ubuntu' && node['platform_version'].to_f < 16.04 + package 'libapache2-mod-php5' + elsif node['platform'] == 'debian' && node['platform_version'].to_f < 9 + package 'libapache2-mod-php5' + else + package 'libapache2-mod-php' + end +when 'arch' + package 'php-apache' do + notifies :run, 'execute[generate-module-list]', :immediately + end +when 'rhel', 'amazon' + package 'which' + package 'php package' do + if node['platform_version'].to_f < 6.0 && node['platform'] != 'amazon' + package_name 'php53' + else + package_name 'php' + end + notifies :run, 'execute[generate-module-list]', :immediately + not_if 'which php' + end +when 'fedora' + package 'which' + package 'php' do + notifies :run, 'execute[generate-module-list]', :immediately + not_if 'which php' + end +when 'suse' + package 'which' + package 'php' do + notifies :run, 'execute[generate-module-list]', :immediately + not_if 'which php' + end +when 'freebsd' + %w(php56 libxml2).each do |pkg| + package pkg + end + %w(mod_php56).each do |pkg| + package pkg do + options '-I' + end + end +end unless node['apache']['mod_php']['install_method'] == 'source' + +case node['platform_family'] +when 'debian' + # on debian plaform_family php creates newly named incompatible config + file "#{node['apache']['dir']}/mods-available/php7.0.conf" do + content '# conf is under mods-available/php.conf - apache2 cookbook\n' + end + + file "#{node['apache']['dir']}/mods-available/php7.0.load" do + content '# conf is under mods-available/php.load - apache2 cookbook\n' + end +when 'rhel', 'fedora', 'suse', 'amazon' + file "#{node['apache']['dir']}/conf.d/php.conf" do + content '# conf is under mods-available/php.conf - apache2 cookbook\n' + only_if { ::Dir.exist?("#{node['apache']['dir']}/conf.d") } + end +end + +template "#{node['apache']['dir']}/mods-available/php.conf" do + source 'mods/php.conf.erb' + mode '0644' + notifies :reload, 'service[apache2]', :delayed +end + +apache_module node['apache']['mod_php']['module_name'] do + conf false + filename node['apache']['mod_php']['so_filename'] +end diff --git a/cookbooks/apache2/recipes/mod_php5.rb b/cookbooks/apache2/recipes/mod_php5.rb index d252cf5..b14bb41 100644 --- a/cookbooks/apache2/recipes/mod_php5.rb +++ b/cookbooks/apache2/recipes/mod_php5.rb @@ -1,10 +1,10 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_php5 # -# Copyright 2008-2013, Chef Software, Inc. -# Copyright 2014, OneHealth Solutions, Inc. -# Copyright 2014, Viverae, Inc. +# Copyright:: 2008-2013, Chef Software, Inc. +# Copyright:: 2014, OneHealth Solutions, Inc. +# Copyright:: 2014, Viverae, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -18,55 +18,5 @@ # See the License for the specific language governing permissions and # limitations under the License. # - -if node['apache']['mpm'] != 'prefork' - Chef::Log.warn('apache2::mod_php5 generally is expected to be run under a non-threaded MPM, such as prefork') - Chef::Log.warn('See http://php.net/manual/en/faq.installation.php#faq.installation.apache2') - Chef::Log.warn("Currently the apache2 cookbook is configured to use the '#{node['apache']['mpm']}' MPM") -end - -case node['platform_family'] -when 'debian' - package 'libapache2-mod-php5' -when 'arch' - package 'php-apache' do - notifies :run, 'execute[generate-module-list]', :immediately - end -when 'rhel' - package 'which' - package 'php package' do - if node['platform_version'].to_f < 6.0 - package_name 'php53' - else - package_name 'php' - end - notifies :run, 'execute[generate-module-list]', :immediately - not_if 'which php' - end -when 'fedora' - package 'which' - package 'php' do - notifies :run, 'execute[generate-module-list]', :immediately - not_if 'which php' - end -when 'suse' - package 'which' - package 'php' do - notifies :run, 'execute[generate-module-list]', :immediately - not_if 'which php' - end -when 'freebsd' - %w(php5 mod_php5 libxml2).each do |pkg| - package pkg - end -end unless node['apache']['mod_php5']['install_method'] == 'source' - -file "#{node['apache']['dir']}/conf.d/php.conf" do - action :delete - backup false -end - -apache_module 'php5' do - conf true - filename node['apache']['mod_php5']['so_filename'] -end +log 'apache2::mod_php5 is deprecated in favor of apache2::mod_php. Please adjust your cookbooks' +include_recipe 'apache2::mod_php' diff --git a/cookbooks/apache2/recipes/mod_privileges.rb b/cookbooks/apache2/recipes/mod_privileges.rb new file mode 100644 index 0000000..d122cb3 --- /dev/null +++ b/cookbooks/apache2/recipes/mod_privileges.rb @@ -0,0 +1,26 @@ +# +# Cookbook:: apache2 +# Recipe:: mod_privileges +# +# Copyright:: 2016, Alexander van Zoest +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# https://httpd.apache.org/docs/trunk/mod/mod_privileges.html +# Available in Apache 2.3 and up, on Solaris 10 and OpenSolaris platforms +if node['apache']['version'] == '2.4' && node['platform_family'] == 'solaris' + apache_module 'privileges' +else + log 'Ignoring apache2::mod_privileges. Not available until apache 2.3 and only on Solaris' +end diff --git a/cookbooks/apache2/recipes/mod_proxy.rb b/cookbooks/apache2/recipes/mod_proxy.rb index 5f0afe3..d936d24 100644 --- a/cookbooks/apache2/recipes/mod_proxy.rb +++ b/cookbooks/apache2/recipes/mod_proxy.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_proxy # -# Copyright 2008-2013, Chef Software, Inc. +# Copyright:: 2008-2013, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -19,4 +19,7 @@ apache_module 'proxy' do conf true + if node['platform'] == 'ubuntu' && node['platform_version'].to_f == 12.04 + restart true + end end diff --git a/cookbooks/apache2/recipes/mod_proxy_ajp.rb b/cookbooks/apache2/recipes/mod_proxy_ajp.rb index 786cc55..ae5f6f9 100644 --- a/cookbooks/apache2/recipes/mod_proxy_ajp.rb +++ b/cookbooks/apache2/recipes/mod_proxy_ajp.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_proxy_ajp # -# Copyright 2008-2013, Chef Software, Inc. +# Copyright:: 2008-2013, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_proxy_balancer.rb b/cookbooks/apache2/recipes/mod_proxy_balancer.rb index 3c1773f..2c4725d 100644 --- a/cookbooks/apache2/recipes/mod_proxy_balancer.rb +++ b/cookbooks/apache2/recipes/mod_proxy_balancer.rb @@ -1,9 +1,9 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_proxy_balancer # -# Copyright 2008-2013, Chef Software, Inc. -# Copyright 2014, OneHealth Solutions, Inc. +# Copyright:: 2008-2013, Chef Software, Inc. +# Copyright:: 2014, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_proxy_connect.rb b/cookbooks/apache2/recipes/mod_proxy_connect.rb index a25514e..3822afb 100644 --- a/cookbooks/apache2/recipes/mod_proxy_connect.rb +++ b/cookbooks/apache2/recipes/mod_proxy_connect.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_proxy_connect # -# Copyright 2008-2013, Chef Software, Inc. +# Copyright:: 2008-2013, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_proxy_express.rb b/cookbooks/apache2/recipes/mod_proxy_express.rb index 5f28763..642a22a 100644 --- a/cookbooks/apache2/recipes/mod_proxy_express.rb +++ b/cookbooks/apache2/recipes/mod_proxy_express.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_proxy_express # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_proxy_fcgi.rb b/cookbooks/apache2/recipes/mod_proxy_fcgi.rb index e265546..1f795c2 100644 --- a/cookbooks/apache2/recipes/mod_proxy_fcgi.rb +++ b/cookbooks/apache2/recipes/mod_proxy_fcgi.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_proxy_fcgi # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_proxy_fdpass.rb b/cookbooks/apache2/recipes/mod_proxy_fdpass.rb index 58d7bb3..8a976bb 100644 --- a/cookbooks/apache2/recipes/mod_proxy_fdpass.rb +++ b/cookbooks/apache2/recipes/mod_proxy_fdpass.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_proxy_fdpass # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_proxy_ftp.rb b/cookbooks/apache2/recipes/mod_proxy_ftp.rb index 9e3ca10..59e3def 100644 --- a/cookbooks/apache2/recipes/mod_proxy_ftp.rb +++ b/cookbooks/apache2/recipes/mod_proxy_ftp.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_proxy_ftp # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_proxy_html.rb b/cookbooks/apache2/recipes/mod_proxy_html.rb index 8f0faa8..68f456b 100644 --- a/cookbooks/apache2/recipes/mod_proxy_html.rb +++ b/cookbooks/apache2/recipes/mod_proxy_html.rb @@ -1,9 +1,9 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_proxy_html # -# Copyright 2013, OneHealth Solutions, Inc. -# Copyright 2015, Alexander van Zoest +# Copyright:: 2013, OneHealth Solutions, Inc. +# Copyright:: 2015, Alexander van Zoest # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -18,7 +18,7 @@ # limitations under the License. # -if node['apache']['version'] != '2.4' && platform_family == 'debian' +if node['apache']['version'] != '2.4' && node['platform_family'] == 'debian' package 'libapache2-mod-proxy-html' end diff --git a/cookbooks/apache2/recipes/mod_proxy_http.rb b/cookbooks/apache2/recipes/mod_proxy_http.rb index 358d244..c1db7d6 100644 --- a/cookbooks/apache2/recipes/mod_proxy_http.rb +++ b/cookbooks/apache2/recipes/mod_proxy_http.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_proxy_http # -# Copyright 2008-2013, Chef Software, Inc. +# Copyright:: 2008-2013, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_proxy_scgi.rb b/cookbooks/apache2/recipes/mod_proxy_scgi.rb index 60a84ae..75f500c 100644 --- a/cookbooks/apache2/recipes/mod_proxy_scgi.rb +++ b/cookbooks/apache2/recipes/mod_proxy_scgi.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_proxy_scgi # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_proxy_wstunnel.rb b/cookbooks/apache2/recipes/mod_proxy_wstunnel.rb index 8e9dcae..316fecc 100644 --- a/cookbooks/apache2/recipes/mod_proxy_wstunnel.rb +++ b/cookbooks/apache2/recipes/mod_proxy_wstunnel.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_proxy_wstunnel # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_python.rb b/cookbooks/apache2/recipes/mod_python.rb index f1a3681..84d30a1 100644 --- a/cookbooks/apache2/recipes/mod_python.rb +++ b/cookbooks/apache2/recipes/mod_python.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_python # -# Copyright 2008-2013, Chef Software, Inc. +# Copyright:: 2008-2013, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -24,7 +24,7 @@ when 'suse' package 'apache2-mod_python' do notifies :run, 'execute[generate-module-list]', :immediately end -when 'rhel', 'fedora' +when 'rhel', 'fedora', 'amazon' package 'mod_python' do notifies :run, 'execute[generate-module-list]', :immediately end @@ -37,8 +37,8 @@ when 'freebsd' end file "#{node['apache']['dir']}/conf.d/python.conf" do - action :delete - backup false + content '# conf is under mods-available/python.conf - apache2 cookbook\n' + only_if { ::Dir.exist?("#{node['apache']['dir']}/conf.d") } end apache_module 'python' diff --git a/cookbooks/apache2/recipes/mod_ratelimit.rb b/cookbooks/apache2/recipes/mod_ratelimit.rb index d66111d..ca00bf4 100644 --- a/cookbooks/apache2/recipes/mod_ratelimit.rb +++ b/cookbooks/apache2/recipes/mod_ratelimit.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_ratelimit # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_reflector.rb b/cookbooks/apache2/recipes/mod_reflector.rb index 3645e78..c495f49 100644 --- a/cookbooks/apache2/recipes/mod_reflector.rb +++ b/cookbooks/apache2/recipes/mod_reflector.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_reflector # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_remoteip.rb b/cookbooks/apache2/recipes/mod_remoteip.rb index fd6d313..d55cfb5 100644 --- a/cookbooks/apache2/recipes/mod_remoteip.rb +++ b/cookbooks/apache2/recipes/mod_remoteip.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_remoteip # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_reqtimeout.rb b/cookbooks/apache2/recipes/mod_reqtimeout.rb index 29f4ee1..5e157d9 100644 --- a/cookbooks/apache2/recipes/mod_reqtimeout.rb +++ b/cookbooks/apache2/recipes/mod_reqtimeout.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_reqtimeout # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_request.rb b/cookbooks/apache2/recipes/mod_request.rb index 7a036e4..5b65513 100644 --- a/cookbooks/apache2/recipes/mod_request.rb +++ b/cookbooks/apache2/recipes/mod_request.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_request # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_rewrite.rb b/cookbooks/apache2/recipes/mod_rewrite.rb index 778cbae..11c2b11 100644 --- a/cookbooks/apache2/recipes/mod_rewrite.rb +++ b/cookbooks/apache2/recipes/mod_rewrite.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_rewrite # -# Copyright 2008-2013, Chef Software, Inc. +# Copyright:: 2008-2013, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_sed.rb b/cookbooks/apache2/recipes/mod_sed.rb index ede8049..5a4f2d8 100644 --- a/cookbooks/apache2/recipes/mod_sed.rb +++ b/cookbooks/apache2/recipes/mod_sed.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_sed # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_session.rb b/cookbooks/apache2/recipes/mod_session.rb index 92093f5..7d88cd6 100644 --- a/cookbooks/apache2/recipes/mod_session.rb +++ b/cookbooks/apache2/recipes/mod_session.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_session # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_session_cookie.rb b/cookbooks/apache2/recipes/mod_session_cookie.rb index a416248..cf12a8e 100644 --- a/cookbooks/apache2/recipes/mod_session_cookie.rb +++ b/cookbooks/apache2/recipes/mod_session_cookie.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_session_cookie # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_session_crypto.rb b/cookbooks/apache2/recipes/mod_session_crypto.rb index 002c551..12c0db2 100644 --- a/cookbooks/apache2/recipes/mod_session_crypto.rb +++ b/cookbooks/apache2/recipes/mod_session_crypto.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_session_crypto # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_session_dbd.rb b/cookbooks/apache2/recipes/mod_session_dbd.rb index 74a7e72..218de64 100644 --- a/cookbooks/apache2/recipes/mod_session_dbd.rb +++ b/cookbooks/apache2/recipes/mod_session_dbd.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_session_dbd # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_setenvif.rb b/cookbooks/apache2/recipes/mod_setenvif.rb index 25c122f..e5847f5 100644 --- a/cookbooks/apache2/recipes/mod_setenvif.rb +++ b/cookbooks/apache2/recipes/mod_setenvif.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_setenvif # -# Copyright 2008-2013, Chef Software, Inc. +# Copyright:: 2008-2013, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_slotmem_plain.rb b/cookbooks/apache2/recipes/mod_slotmem_plain.rb index acc1545..45bdd26 100644 --- a/cookbooks/apache2/recipes/mod_slotmem_plain.rb +++ b/cookbooks/apache2/recipes/mod_slotmem_plain.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_slotmem_plain # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_slotmem_shm.rb b/cookbooks/apache2/recipes/mod_slotmem_shm.rb index d2c45eb..774cf85 100644 --- a/cookbooks/apache2/recipes/mod_slotmem_shm.rb +++ b/cookbooks/apache2/recipes/mod_slotmem_shm.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_slotmem_shm # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_socache_dbm.rb b/cookbooks/apache2/recipes/mod_socache_dbm.rb index 37a6ff2..6aead61 100644 --- a/cookbooks/apache2/recipes/mod_socache_dbm.rb +++ b/cookbooks/apache2/recipes/mod_socache_dbm.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_socache_dbm # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_socache_dc.rb b/cookbooks/apache2/recipes/mod_socache_dc.rb new file mode 100644 index 0000000..0bbda31 --- /dev/null +++ b/cookbooks/apache2/recipes/mod_socache_dc.rb @@ -0,0 +1,20 @@ +# +# Cookbook:: apache2 +# Recipe:: mod_socache_dc +# +# Copyright:: 2016, Alexander van Zoest +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +apache_module 'socache_dc' diff --git a/cookbooks/apache2/recipes/mod_socache_memcache.rb b/cookbooks/apache2/recipes/mod_socache_memcache.rb index 6c91060..0897b98 100644 --- a/cookbooks/apache2/recipes/mod_socache_memcache.rb +++ b/cookbooks/apache2/recipes/mod_socache_memcache.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_socache_memcache # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_socache_shmcb.rb b/cookbooks/apache2/recipes/mod_socache_shmcb.rb index eac6522..31733fe 100644 --- a/cookbooks/apache2/recipes/mod_socache_shmcb.rb +++ b/cookbooks/apache2/recipes/mod_socache_shmcb.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_socache_shmcb # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_speling.rb b/cookbooks/apache2/recipes/mod_speling.rb index 0c76d04..b4b74c5 100644 --- a/cookbooks/apache2/recipes/mod_speling.rb +++ b/cookbooks/apache2/recipes/mod_speling.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_speling # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_ssl.rb b/cookbooks/apache2/recipes/mod_ssl.rb index 0d749b0..9b34516 100644 --- a/cookbooks/apache2/recipes/mod_ssl.rb +++ b/cookbooks/apache2/recipes/mod_ssl.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_ssl # -# Copyright 2008-2013, Chef Software, Inc. +# Copyright:: 2008-2013, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -16,20 +16,21 @@ # See the License for the specific language governing permissions and # limitations under the License. # -unless node['apache']['listen_ports'].include?(node['apache']['mod_ssl']['port']) - node.default['apache']['listen_ports'] = node['apache']['listen_ports'] + [node['apache']['mod_ssl']['port']] +if node['apache']['listen'] == ['*:80'] + node.default['apache']['listen'] = ['*:80', "*:#{node['apache']['mod_ssl']['port']}"] end include_recipe 'apache2::default' -if platform_family?('rhel', 'fedora', 'suse') +if platform_family?('rhel', 'fedora', 'suse', 'amazon') package node['apache']['mod_ssl']['pkg_name'] do notifies :run, 'execute[generate-module-list]', :immediately + not_if { platform_family?('suse') } end file "#{node['apache']['dir']}/conf.d/ssl.conf" do - action :delete - backup false + content '# SSL Conf is under mods-available/ssl.conf - apache2 cookbook\n' + only_if { ::Dir.exist?("#{node['apache']['dir']}/conf.d") } end end diff --git a/cookbooks/apache2/recipes/mod_status.rb b/cookbooks/apache2/recipes/mod_status.rb index 60f5f75..6ec4f0c 100644 --- a/cookbooks/apache2/recipes/mod_status.rb +++ b/cookbooks/apache2/recipes/mod_status.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_status # -# Copyright 2008-2012, Chef Software, Inc. +# Copyright:: 2008-2012, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_substitute.rb b/cookbooks/apache2/recipes/mod_substitute.rb index 393e3fc..e10cb53 100644 --- a/cookbooks/apache2/recipes/mod_substitute.rb +++ b/cookbooks/apache2/recipes/mod_substitute.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_substitute # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_suexec.rb b/cookbooks/apache2/recipes/mod_suexec.rb index 75172aa..94213d5 100644 --- a/cookbooks/apache2/recipes/mod_suexec.rb +++ b/cookbooks/apache2/recipes/mod_suexec.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_suexec # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_systemd.rb b/cookbooks/apache2/recipes/mod_systemd.rb index d3f979d..11fdd4b 100644 --- a/cookbooks/apache2/recipes/mod_systemd.rb +++ b/cookbooks/apache2/recipes/mod_systemd.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_systemd # -# Copyright 2008-2013, Chef Software, Inc. +# Copyright:: 2008-2013, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_unique_id.rb b/cookbooks/apache2/recipes/mod_unique_id.rb index cf3fbf4..27e1cb2 100644 --- a/cookbooks/apache2/recipes/mod_unique_id.rb +++ b/cookbooks/apache2/recipes/mod_unique_id.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_unique_id # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_unixd.rb b/cookbooks/apache2/recipes/mod_unixd.rb index d41654b..56891a1 100644 --- a/cookbooks/apache2/recipes/mod_unixd.rb +++ b/cookbooks/apache2/recipes/mod_unixd.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_unixd # -# Copyright 2014, OneHealth Solutions, Inc. +# Copyright:: 2014, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_userdir.rb b/cookbooks/apache2/recipes/mod_userdir.rb index 7d519d4..d56f676 100644 --- a/cookbooks/apache2/recipes/mod_userdir.rb +++ b/cookbooks/apache2/recipes/mod_userdir.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_userdir # -# Copyright 2013, Chef Software, Inc. +# Copyright:: 2013, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_usertrack.rb b/cookbooks/apache2/recipes/mod_usertrack.rb index 6462ee3..2315d12 100644 --- a/cookbooks/apache2/recipes/mod_usertrack.rb +++ b/cookbooks/apache2/recipes/mod_usertrack.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_usertrack # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_version.rb b/cookbooks/apache2/recipes/mod_version.rb new file mode 100644 index 0000000..baad18c --- /dev/null +++ b/cookbooks/apache2/recipes/mod_version.rb @@ -0,0 +1,20 @@ +# +# Cookbook:: apache2 +# Recipe:: mod_version +# +# Copyright:: 2016, Alexander van Zoest +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +apache_module 'version' diff --git a/cookbooks/apache2/recipes/mod_vhost_alias.rb b/cookbooks/apache2/recipes/mod_vhost_alias.rb index a56ecab..5029b04 100644 --- a/cookbooks/apache2/recipes/mod_vhost_alias.rb +++ b/cookbooks/apache2/recipes/mod_vhost_alias.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_vhost_alias # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_watchdog.rb b/cookbooks/apache2/recipes/mod_watchdog.rb new file mode 100644 index 0000000..18f8030 --- /dev/null +++ b/cookbooks/apache2/recipes/mod_watchdog.rb @@ -0,0 +1,23 @@ +# +# Cookbook:: apache2 +# Recipe:: mod_watchdog +# +# Copyright:: 2016, Alexander van Zoest +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# http://httpd.apache.org/docs/2.4/mod/mod_watchdog.html +# To allow a module to use mod_watchdog functionality be loaded before the calling module. +# see https://github.com/sous-chefs/apache2/issues/224 +apache_module 'watchdog' diff --git a/cookbooks/apache2/recipes/mod_wsgi.rb b/cookbooks/apache2/recipes/mod_wsgi.rb index 3505e82..024d6d4 100644 --- a/cookbooks/apache2/recipes/mod_wsgi.rb +++ b/cookbooks/apache2/recipes/mod_wsgi.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_wsgi # -# Copyright 2008-2013, Chef Software, Inc. +# Copyright:: 2008-2013, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -20,15 +20,15 @@ case node['platform_family'] when 'debian' package 'libapache2-mod-wsgi' -when 'rhel', 'fedora', 'arch' +when 'rhel', 'fedora', 'arch', 'amazon' package 'mod_wsgi' do notifies :run, 'execute[generate-module-list]', :immediately end end file "#{node['apache']['dir']}/conf.d/wsgi.conf" do - action :delete - backup false + content '# conf is under mods-available/wsgi.conf - apache2 cookbook\n' + only_if { ::Dir.exist?("#{node['apache']['dir']}/conf.d") } end apache_module 'wsgi' diff --git a/cookbooks/apache2/recipes/mod_xml2enc.rb b/cookbooks/apache2/recipes/mod_xml2enc.rb index 76ab418..b39a2e8 100644 --- a/cookbooks/apache2/recipes/mod_xml2enc.rb +++ b/cookbooks/apache2/recipes/mod_xml2enc.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_xml2enc # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mod_xsendfile.rb b/cookbooks/apache2/recipes/mod_xsendfile.rb index 8000984..a33ee0f 100644 --- a/cookbooks/apache2/recipes/mod_xsendfile.rb +++ b/cookbooks/apache2/recipes/mod_xsendfile.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mod_xsendfile # -# Copyright 2011-2013, CustomInk, LLC. +# Copyright:: 2011-2013, CustomInk, LLC. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -24,15 +24,15 @@ when 'suse' end when 'debian' package 'libapache2-mod-xsendfile' -when 'rhel', 'fedora' +when 'rhel', 'fedora', 'amazon' package 'mod_xsendfile' do notifies :run, 'execute[generate-module-list]', :immediately end end file "#{node['apache']['dir']}/conf.d/xsendfile.conf" do - action :delete - backup false + content '# conf is under mods-available/xsendfile.conf - apache2 cookbook\n' + only_if { ::Dir.exist?("#{node['apache']['dir']}/conf.d") } end apache_module 'xsendfile' diff --git a/cookbooks/apache2/recipes/mpm_event.rb b/cookbooks/apache2/recipes/mpm_event.rb index 3f27aea..b806d3e 100644 --- a/cookbooks/apache2/recipes/mpm_event.rb +++ b/cookbooks/apache2/recipes/mpm_event.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mpm_event # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mpm_prefork.rb b/cookbooks/apache2/recipes/mpm_prefork.rb index de30821..6a0d025 100644 --- a/cookbooks/apache2/recipes/mpm_prefork.rb +++ b/cookbooks/apache2/recipes/mpm_prefork.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mpm_prefork # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/recipes/mpm_worker.rb b/cookbooks/apache2/recipes/mpm_worker.rb index 86a01a5..755a77a 100644 --- a/cookbooks/apache2/recipes/mpm_worker.rb +++ b/cookbooks/apache2/recipes/mpm_worker.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: apache2 +# Cookbook:: apache2 # Recipe:: mpm_worker # -# Copyright 2013, OneHealth Solutions, Inc. +# Copyright:: 2013, OneHealth Solutions, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/apache2/templates/default/a2disconf.erb b/cookbooks/apache2/templates/default/a2disconf.erb index 6c2c262..aec9f23 100644 --- a/cookbooks/apache2/templates/default/a2disconf.erb +++ b/cookbooks/apache2/templates/default/a2disconf.erb @@ -1,4 +1,4 @@ -#!/usr/bin/perl -w +#!<%= node['platform_family'] == 'freebsd' ? '/usr/local/bin/perl' : '/usr/bin/perl'%> -w # # a2enmod by Stefan Fritsch # Licensed under Apache License 2.0 diff --git a/cookbooks/apache2/templates/default/a2dismod.erb b/cookbooks/apache2/templates/default/a2dismod.erb index 6c2c262..aec9f23 100644 --- a/cookbooks/apache2/templates/default/a2dismod.erb +++ b/cookbooks/apache2/templates/default/a2dismod.erb @@ -1,4 +1,4 @@ -#!/usr/bin/perl -w +#!<%= node['platform_family'] == 'freebsd' ? '/usr/local/bin/perl' : '/usr/bin/perl'%> -w # # a2enmod by Stefan Fritsch # Licensed under Apache License 2.0 diff --git a/cookbooks/apache2/templates/default/a2dissite.erb b/cookbooks/apache2/templates/default/a2dissite.erb index 6c2c262..aec9f23 100644 --- a/cookbooks/apache2/templates/default/a2dissite.erb +++ b/cookbooks/apache2/templates/default/a2dissite.erb @@ -1,4 +1,4 @@ -#!/usr/bin/perl -w +#!<%= node['platform_family'] == 'freebsd' ? '/usr/local/bin/perl' : '/usr/bin/perl'%> -w # # a2enmod by Stefan Fritsch # Licensed under Apache License 2.0 diff --git a/cookbooks/apache2/templates/default/a2enconf.erb b/cookbooks/apache2/templates/default/a2enconf.erb index 6c2c262..aec9f23 100644 --- a/cookbooks/apache2/templates/default/a2enconf.erb +++ b/cookbooks/apache2/templates/default/a2enconf.erb @@ -1,4 +1,4 @@ -#!/usr/bin/perl -w +#!<%= node['platform_family'] == 'freebsd' ? '/usr/local/bin/perl' : '/usr/bin/perl'%> -w # # a2enmod by Stefan Fritsch # Licensed under Apache License 2.0 diff --git a/cookbooks/apache2/templates/default/a2enmod.erb b/cookbooks/apache2/templates/default/a2enmod.erb index 6c2c262..aec9f23 100644 --- a/cookbooks/apache2/templates/default/a2enmod.erb +++ b/cookbooks/apache2/templates/default/a2enmod.erb @@ -1,4 +1,4 @@ -#!/usr/bin/perl -w +#!<%= node['platform_family'] == 'freebsd' ? '/usr/local/bin/perl' : '/usr/bin/perl'%> -w # # a2enmod by Stefan Fritsch # Licensed under Apache License 2.0 diff --git a/cookbooks/apache2/templates/default/a2ensite.erb b/cookbooks/apache2/templates/default/a2ensite.erb index 6c2c262..aec9f23 100644 --- a/cookbooks/apache2/templates/default/a2ensite.erb +++ b/cookbooks/apache2/templates/default/a2ensite.erb @@ -1,4 +1,4 @@ -#!/usr/bin/perl -w +#!<%= node['platform_family'] == 'freebsd' ? '/usr/local/bin/perl' : '/usr/bin/perl'%> -w # # a2enmod by Stefan Fritsch # Licensed under Apache License 2.0 diff --git a/cookbooks/apache2/templates/default/apache2.conf.erb b/cookbooks/apache2/templates/default/apache2.conf.erb index 72f93bf..13d132d 100644 --- a/cookbooks/apache2/templates/default/apache2.conf.erb +++ b/cookbooks/apache2/templates/default/apache2.conf.erb @@ -93,9 +93,9 @@ AccessFileName <%= node['apache']['access_file_name'] %> # <% access_file_name_prefix = node['apache']['access_file_name'][0..2] if !node['apache']['access_file_name'].empty? if access_file_name_prefix != '.ht' - file_name_prefix = '(' + access_file_name_prefix + '|.ht)' + file_name_prefix = '(' + access_file_name_prefix + '|\.ht)' else - file_name_prefix = '.ht' + file_name_prefix = '\.ht' end %> "> @@ -147,7 +147,7 @@ ErrorLog <%= node['apache']['log_dir'] %>/<%= node['apache']['error_log'] %> # Possible values include: debug, info, notice, warn, error, crit, # alert, emerg. # -LogLevel warn +LogLevel <%= node['apache']['log_level'] %> # COOK-1021: Dummy LoadModule directive to aid module installations #LoadModule dummy_module modules/mod_dummy.so diff --git a/cookbooks/apache2/templates/default/default-site.conf.erb b/cookbooks/apache2/templates/default/default-site.conf.erb index d0e299a..9ff1961 100644 --- a/cookbooks/apache2/templates/default/default-site.conf.erb +++ b/cookbooks/apache2/templates/default/default-site.conf.erb @@ -1,3 +1,6 @@ +<% if node['apache']['version'] != '2.4' -%> +NameVirtualHost *:<%= node['apache']['default_site_port'] %> +<% end -%> > ServerAdmin <%= node['apache']['contact'] %> @@ -37,7 +40,7 @@ # Possible values include: debug, info, notice, warn, error, crit, # alert, emerg. - LogLevel warn + LogLevel <%= node['apache']['log_level'] %> CustomLog <%= node['apache']['log_dir'] %>/<%= node['apache']['access_log'] %> combined ServerSignature On @@ -56,7 +59,7 @@ <% end -%> - <% if %w{ rhel fedora }.include?(node['platform_family']) -%> + <% if %w{ rhel fedora amazon }.include?(node['platform_family']) -%> # # This configuration file enables the default "Welcome" # page if there is no default index page present for diff --git a/cookbooks/apache2/templates/default/mods/fcgid.conf.erb b/cookbooks/apache2/templates/default/mods/fcgid.conf.erb index d13e8a6..597b7dc 100644 --- a/cookbooks/apache2/templates/default/mods/fcgid.conf.erb +++ b/cookbooks/apache2/templates/default/mods/fcgid.conf.erb @@ -3,7 +3,7 @@ IPCConnectTimeout 20 -<% if %w[rhel fedora].include?(node['platform_family']) -%> +<% if (node['platform_family'] == 'rhel') && (node['platform_version'].to_i == 6) -%> # Sane place to put sockets and shared memory file SocketPath run/mod_fcgid SharememPath run/mod_fcgid/fcgid_shm diff --git a/cookbooks/apache2/templates/default/mods/mpm_prefork.conf.erb b/cookbooks/apache2/templates/default/mods/mpm_prefork.conf.erb index 62b5503..e1d5dec 100644 --- a/cookbooks/apache2/templates/default/mods/mpm_prefork.conf.erb +++ b/cookbooks/apache2/templates/default/mods/mpm_prefork.conf.erb @@ -9,6 +9,7 @@ StartServers <%= node['apache']['prefork']['startservers'] %> MinSpareServers <%= node['apache']['prefork']['minspareservers'] %> MaxSpareServers <%= node['apache']['prefork']['maxspareservers'] %> + ServerLimit <%= node['apache']['prefork']['serverlimit'] %> MaxRequestWorkers <%= node['apache']['prefork']['maxrequestworkers'] %> MaxConnectionsPerChild <%= node['apache']['prefork']['maxconnectionsperchild'] %> <% else -%> diff --git a/cookbooks/apache2/templates/default/mods/php.conf.erb b/cookbooks/apache2/templates/default/mods/php.conf.erb new file mode 100644 index 0000000..bdf590b --- /dev/null +++ b/cookbooks/apache2/templates/default/mods/php.conf.erb @@ -0,0 +1,35 @@ + + SetHandler application/x-httpd-php + + + SetHandler application/x-httpd-php-source + # Deny access to raw php sources by default + # To re-enable it's recommended to enable access to the files + # only in specific virtual host or directory +<% if node['apache']['version'] == '2.4' -%> + Require all denied +<% else -%> + Order Deny,Allow + Deny from all +<% end -%> + +# Deny access to files without filename (e.g. '.php') + +<% if node['apache']['version'] == '2.4' -%> + Require all denied +<% else -%> + Order Deny,Allow + Deny from all +<% end -%> + + +# Running PHP scripts in user directories is disabled by default +# +# To re-enable PHP in user directories comment the following lines +# (from to .) Do NOT set it to On as it +# prevents .htaccess files from disabling it. + + + php_admin_value engine Off + + diff --git a/cookbooks/apache2/templates/default/mods/php5.conf.erb b/cookbooks/apache2/templates/default/mods/php5.conf.erb deleted file mode 100644 index b11f1b2..0000000 --- a/cookbooks/apache2/templates/default/mods/php5.conf.erb +++ /dev/null @@ -1,37 +0,0 @@ - - - SetHandler application/x-httpd-php - - - SetHandler application/x-httpd-php-source - # Deny access to raw php sources by default - # To re-enable it's recommended to enable access to the files - # only in specific virtual host or directory -<% if node['apache']['version'] == '2.4' -%> - Require all denied -<% else -%> - Order Deny,Allow - Deny from all -<% end -%> - - # Deny access to files without filename (e.g. '.php') - -<% if node['apache']['version'] == '2.4' -%> - Require all denied -<% else -%> - Order Deny,Allow - Deny from all -<% end -%> - - - # Running PHP scripts in user directories is disabled by default - # - # To re-enable PHP in user directories comment the following lines - # (from to .) Do NOT set it to On as it - # prevents .htaccess files from disabling it. - - - php_admin_value engine Off - - - diff --git a/cookbooks/apache2/templates/default/port_apache.erb b/cookbooks/apache2/templates/default/port_apache.erb index 64a0f8e..9ac7474 100644 --- a/cookbooks/apache2/templates/default/port_apache.erb +++ b/cookbooks/apache2/templates/default/port_apache.erb @@ -1,3 +1,3 @@ -<% node['apache']['listen_ports'].each do |port| -%> +<% node['apache']['listen'].values.map(&:to_a).flatten.uniq do |port| -%> -A FWR -p tcp -m tcp --dport <%= port %> -j ACCEPT <% end %> diff --git a/cookbooks/apache2/templates/default/ports.conf.erb b/cookbooks/apache2/templates/default/ports.conf.erb index d3a2ca2..129d06a 100644 --- a/cookbooks/apache2/templates/default/ports.conf.erb +++ b/cookbooks/apache2/templates/default/ports.conf.erb @@ -1,11 +1,6 @@ # This file was generated by Chef for <%= node['fqdn'] %>. # Do NOT modify this file by hand! -<% node['apache']['listen_ports'].map(&:to_i).uniq.each do |port| -%> -<% node['apache']['listen_addresses'].uniq.each do |address| -%> -Listen <%= address.length > 0 ? "#{address}:" : '' %><%= port %> -<% end -%> -<% if node['apache']['version'] != "2.4" -%> -NameVirtualHost *:<%= port %> -<% end -%> +<% Apache2::Listen.merge_listen_attributes(node).each do |addr| -%> +Listen <%= addr %> <% end -%> diff --git a/cookbooks/apache2/templates/default/security.conf.erb b/cookbooks/apache2/templates/default/security.conf.erb index c0a2d45..1913ad3 100644 --- a/cookbooks/apache2/templates/default/security.conf.erb +++ b/cookbooks/apache2/templates/default/security.conf.erb @@ -1,16 +1,3 @@ -# -# Disable access to the entire file system except for the directories that -# are explicitly allowed later. -# -# This currently breaks the configurations that come with some web application -# Debian packages. It will be made the default for the release after lenny. -# -# -# AllowOverride None -# Order Deny,Allow -# Deny from all -# - # Changing the following options will not really affect the security of the # server, but might make attacks slightly more difficult in some cases. diff --git a/cookbooks/apache2/templates/default/web_app.conf.erb b/cookbooks/apache2/templates/default/web_app.conf.erb index d3e8b71..d007ee5 100644 --- a/cookbooks/apache2/templates/default/web_app.conf.erb +++ b/cookbooks/apache2/templates/default/web_app.conf.erb @@ -1,4 +1,7 @@ -> +<% if node['apache']['version'] != '2.4' -%> +NameVirtualHost *:<%= @params[:server_port] %> +<% end -%> +> ServerName <%= @params[:server_name] %> <% if @params[:server_aliases] -%> ServerAlias <%= @params[:server_aliases].join " " %> diff --git a/cookbooks/chef_handler/CHANGELOG.md b/cookbooks/chef_handler/CHANGELOG.md deleted file mode 100644 index 707ca43..0000000 --- a/cookbooks/chef_handler/CHANGELOG.md +++ /dev/null @@ -1,56 +0,0 @@ -# chef_handler cookbook CHANGELOG -This file is used to list changes made in each version of the chef_handler cookbook. - -## v1.3.0 (2016-02-16) -- Added state attributes to the custom resource -- Added source_url and issues_url to metadata.rb -- Replaced attributes for root user and group with the Ohai defined values to simplify the logic of the cookbook -- Added lint, unit, and itegration testing in Travis CI -- Added Test Kitchen testing of the recipes and the custom resource via a test cookbook -- Added Berksfile -- Added chefignore and .gitignore files -- Added .rubocop.yml config and resolve multiple issues -- Updated contributing and testing docs to the latest -- Added all testing dependencies to the Gemfile -- Added maintainers.md and maintainers.toml files -- Expanded the Rakefile for simplified testing - -## v1.2.0 (2015-06-25) -- Move to support Chef 12+ only. Removes old 'handler class reload' behavior - it isn't necessary because chef-client forks and doesn't share a process between runs. - -## v1.1.9 (2015-05-26) -- Bugfixes from 1.1.8 - loading without source is not allowed again. Class unloading is performed more carefully. Tests for resource providers. - -## v1.1.8 (2015-05-14) -- Updated Contribution and Readme docs -- Fix ChefSpec matchers -- Allow handler to load classes when no source is provided. - -## v1.1.6 (2014-04-09) -- [COOK-4494] - Add ChefSpec matchers - -## v1.1.5 (2014-02-25) -- [COOK-4117] - use the correct scope when searching the children class name - -## v1.1.4 -- [COOK-2146] - style updates - -## v1.1.2 -- [COOK-1989] - fix scope for handler local variable to the enable block - -## v1.1.0 -- [COOK-1645] - properly delete old handlers -- [COOK-1322] - support platforms that use 'wheel' as root group' - -## v1.0.8 -- [COOK-1177] - doesn't work on windows due to use of unix specific attributes - -## v1.0.6 -- [COOK-1069] - typo in chef_handler readme - -## v1.0.4 -- [COOK-654] dont try and access a class before it has been loaded -- fix bad boolean check (if vs unless) - -## v1.0.2 -- [COOK-620] ensure handler code is reloaded during daemonized chef runs diff --git a/cookbooks/chef_handler/README.md b/cookbooks/chef_handler/README.md deleted file mode 100644 index 75ec337..0000000 --- a/cookbooks/chef_handler/README.md +++ /dev/null @@ -1,113 +0,0 @@ -# chef_handler Cookbook -[![Build Status](https://travis-ci.org/chef-cookbooks/chef_handler.svg?branch=master)](https://travis-ci.org/chef-cookbooks/chef_handler) [![Cookbook Version](https://img.shields.io/cookbook/v/chef_handler.svg)](https://supermarket.chef.io/cookbooks/chef_handler) - -Creates a configured handler path for distributing [Chef report and exception handlers](http://docs.chef.io/handlers.html). Also exposes an LWRP for enabling Chef handlers from within recipe code (as opposed to hard coding in the client.rb file). This is useful for cookbook authors who may want to ship a product specific handler (see the `cloudkick` cookbook for an example) with their cookbook. - -## Requirements -### Platforms -- Debian/Ubuntu -- RHEL/CentOS/Scientific/Amazon/Oracle -- Windows - -### Chef -- Chef 11+ - -### Cookbooks -- none - -## Attributes -`node['chef_handler']['handler_path']` - location to drop off handlers directory, default is a folder named 'handlers' in Chef's file cache directory - -## Custom Resources -### chef_handler -Requires, configures and enables handlers on the node for the current Chef run. Also has the ability to pass arguments to the handlers initializer. This allows initialization data to be pulled from a node's attribute data. - -It is best to declare `chef_handler` resources early on in the compile phase so they are available to fire for any exceptions during the Chef run. If you have a base role you would want any recipes that register Chef handlers to come first in the run_list. - -#### Actions -- `:enable:` Enables the Chef handler for the current Chef run on the current node -- `:disable:` Disables the Chef handler for the current Chef run on the current node - -#### Attribute Parameters -- `class_name:` name attribute. The name of the handler class (can be module name-spaced). -- `source:` full path to the handler file. can also be a gem path if the handler ships as part of a Ruby gem. -- `arguments:` an array of arguments to pass the handler's class initializer -- `supports:` type of Chef Handler to register as, i.e. :report, :exception or both. default is `:report => true, :exception => true` - -#### Example - -```ruby - # register the Chef::Handler::JsonFile handler - # that ships with the Chef gem - chef_handler "Chef::Handler::JsonFile" do - source "chef/handler/json_file" - arguments :path => '/var/chef/reports' - action :enable - end - - # do the same but during the compile phase - chef_handler "Chef::Handler::JsonFile" do - source "chef/handler/json_file" - arguments :path => '/var/chef/reports' - action :nothing - end.run_action(:enable) - - # handle exceptions only - chef_handler "Chef::Handler::JsonFile" do - source "chef/handler/json_file" - arguments :path => '/var/chef/reports' - supports :exception => true - action :enable - end - - - # enable the CloudkickHandler which was - # dropped off in the default handler path. - # passes the oauth key/secret to the handler's - # intializer. - chef_handler "CloudkickHandler" do - source "#{node['chef_handler']['handler_path']}/cloudkick_handler.rb" - arguments [node['cloudkick']['oauth_key'], node['cloudkick']['oauth_secret']] - action :enable - end -``` - -## Usage -### default -Put the recipe `chef_handler` at the start of the node's run list to make sure that custom handlers are dropped off early on in the Chef run and available for later recipes. - -For information on how to write report and exception handlers for Chef, please see the Chef wiki pages: [https://docs.chef.io/handlers.html](https://docs.chef.io/handlers.html) - -### json_file -Leverages the `chef_handler` LWRP to automatically register the `Chef::Handler::JsonFile` handler that ships as part of Chef. This handler serializes the run status data to a JSON file located at `/var/chef/reports`. - -## Unit Testing -chef_handler provides built in [chefspec](https://github.com/sethvargo/chefspec) matchers for assisting unit tests. These matchers will only be loaded if chefspec is already loaded. Following is an example of asserting against the jsonfile handler: - -```ruby - expect(runner).to enable_chef_handler("Chef::Handler::JsonFile").with( - source: "chef/handler/json_file", - arguments: { :path => '/var/chef/reports'}, - supports: {:exception => true} - ) - end -``` - -## License & Authors -**Author:** Cookbook Engineering Team ([cookbooks@chef.io](mailto:cookbooks@chef.io)) - -**Copyright:** 2011-2016, Chef Software, Inc. - -``` -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -``` diff --git a/cookbooks/chef_handler/files/default/handlers/README b/cookbooks/chef_handler/files/default/handlers/README deleted file mode 100644 index b575066..0000000 --- a/cookbooks/chef_handler/files/default/handlers/README +++ /dev/null @@ -1 +0,0 @@ -This directory contains Chef handlers to distribute to your nodes. diff --git a/cookbooks/chef_handler/libraries/helpers.rb b/cookbooks/chef_handler/libraries/helpers.rb deleted file mode 100644 index 2f36aa6..0000000 --- a/cookbooks/chef_handler/libraries/helpers.rb +++ /dev/null @@ -1,55 +0,0 @@ -# -# Author:: Kartik Cating-Subramanian () -# Copyright:: Copyright (c) 2015-2016 Chef Software, Inc. -# License:: Apache License, Version 2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -module ChefHandler - module Helpers - # Registers a handler in Chef::Config. - # - # @param handler_type [Symbol] such as :report or :exception. - # @param handler [Chef::Handler] handler to register. - def register_handler(handler_type, handler) - Chef::Log.info("Enabling #{handler.class.name} as a #{handler_type} handler.") - Chef::Config.send("#{handler_type}_handlers") << handler - end - - # Removes all handlers that match the given class name in Chef::Config. - # - # @param handler_type [Symbol] such as :report or :exception. - # @param class_full_name [String] such as 'Chef::Handler::ErrorReport'. - def unregister_handler(handler_type, class_full_name) - Chef::Log.info("Disabling #{class_full_name} as a #{handler_type} handler.") - Chef::Config.send("#{handler_type}_handlers").delete_if { |v| v.class.name == class_full_name } - end - - # Walks down the namespace heirarchy to return the class object for the given class name. - # If the class is not available, NameError is thrown. - # - # @param class_full_name [String] full class name such as 'Chef::Handler::Foo' or 'MyHandler'. - # @return [Array] parent class and child class. - def get_class(class_full_name) - ancestors = class_full_name.split('::') - class_name = ancestors.pop - - # We need to search the ancestors only for the first/uppermost namespace of the class, so we - # need to enable the #const_get inherit paramenter only when we are searching in Kernel scope - # (see COOK-4117). - parent = ancestors.inject(Kernel) { |scope, const_name| scope.const_get(const_name, scope === Kernel) } - child = parent.const_get(class_name, parent === Kernel) - [parent, child] - end - end -end diff --git a/cookbooks/chef_handler/libraries/matchers.rb b/cookbooks/chef_handler/libraries/matchers.rb deleted file mode 100644 index f1c2936..0000000 --- a/cookbooks/chef_handler/libraries/matchers.rb +++ /dev/null @@ -1,38 +0,0 @@ -# -# Author:: Douglas Thrift () -# Cookbook Name:: chef_handler -# Library:: matchers -# -# Copyright 2014-2016, Chef Software, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -if defined?(ChefSpec) - chefspec_version = Gem.loaded_specs['chefspec'].version - define_method = if chefspec_version < Gem::Version.new('4.1.0') - ChefSpec::Runner.method(:define_runner_method) - else - ChefSpec.method(:define_matcher) - end - - define_method.call :chef_handler - - def enable_chef_handler(resource_name) - ChefSpec::Matchers::ResourceMatcher.new(:chef_handler, :enable, resource_name) - end - - def disable_chef_handler(resource_name) - ChefSpec::Matchers::ResourceMatcher.new(:chef_handler, :disable, resource_name) - end -end diff --git a/cookbooks/chef_handler/metadata.json b/cookbooks/chef_handler/metadata.json deleted file mode 100644 index 8c776ba..0000000 --- a/cookbooks/chef_handler/metadata.json +++ /dev/null @@ -1 +0,0 @@ -{"name":"chef_handler","version":"1.3.0","description":"Distribute and enable Chef Exception and Report handlers","long_description":"# chef_handler Cookbook\n[![Build Status](https://travis-ci.org/chef-cookbooks/chef_handler.svg?branch=master)](https://travis-ci.org/chef-cookbooks/chef_handler) [![Cookbook Version](https://img.shields.io/cookbook/v/chef_handler.svg)](https://supermarket.chef.io/cookbooks/chef_handler)\n\nCreates a configured handler path for distributing [Chef report and exception handlers](http://docs.chef.io/handlers.html). Also exposes an LWRP for enabling Chef handlers from within recipe code (as opposed to hard coding in the client.rb file). This is useful for cookbook authors who may want to ship a product specific handler (see the `cloudkick` cookbook for an example) with their cookbook.\n\n## Requirements\n### Platforms\n- Debian/Ubuntu\n- RHEL/CentOS/Scientific/Amazon/Oracle\n- Windows\n\n### Chef\n- Chef 11+\n\n### Cookbooks\n- none\n\n## Attributes\n`node['chef_handler']['handler_path']` - location to drop off handlers directory, default is a folder named 'handlers' in Chef's file cache directory\n\n## Custom Resources\n### chef_handler\nRequires, configures and enables handlers on the node for the current Chef run. Also has the ability to pass arguments to the handlers initializer. This allows initialization data to be pulled from a node's attribute data.\n\nIt is best to declare `chef_handler` resources early on in the compile phase so they are available to fire for any exceptions during the Chef run. If you have a base role you would want any recipes that register Chef handlers to come first in the run_list.\n\n#### Actions\n- `:enable:` Enables the Chef handler for the current Chef run on the current node\n- `:disable:` Disables the Chef handler for the current Chef run on the current node\n\n#### Attribute Parameters\n- `class_name:` name attribute. The name of the handler class (can be module name-spaced).\n- `source:` full path to the handler file. can also be a gem path if the handler ships as part of a Ruby gem.\n- `arguments:` an array of arguments to pass the handler's class initializer\n- `supports:` type of Chef Handler to register as, i.e. :report, :exception or both. default is `:report => true, :exception => true`\n\n#### Example\n\n```ruby\n # register the Chef::Handler::JsonFile handler\n # that ships with the Chef gem\n chef_handler \"Chef::Handler::JsonFile\" do\n source \"chef/handler/json_file\"\n arguments :path => '/var/chef/reports'\n action :enable\n end\n\n # do the same but during the compile phase\n chef_handler \"Chef::Handler::JsonFile\" do\n source \"chef/handler/json_file\"\n arguments :path => '/var/chef/reports'\n action :nothing\n end.run_action(:enable)\n\n # handle exceptions only\n chef_handler \"Chef::Handler::JsonFile\" do\n source \"chef/handler/json_file\"\n arguments :path => '/var/chef/reports'\n supports :exception => true\n action :enable\n end\n\n\n # enable the CloudkickHandler which was\n # dropped off in the default handler path.\n # passes the oauth key/secret to the handler's\n # intializer.\n chef_handler \"CloudkickHandler\" do\n source \"#{node['chef_handler']['handler_path']}/cloudkick_handler.rb\"\n arguments [node['cloudkick']['oauth_key'], node['cloudkick']['oauth_secret']]\n action :enable\n end\n```\n\n## Usage\n### default\nPut the recipe `chef_handler` at the start of the node's run list to make sure that custom handlers are dropped off early on in the Chef run and available for later recipes.\n\nFor information on how to write report and exception handlers for Chef, please see the Chef wiki pages: [https://docs.chef.io/handlers.html](https://docs.chef.io/handlers.html)\n\n### json_file\nLeverages the `chef_handler` LWRP to automatically register the `Chef::Handler::JsonFile` handler that ships as part of Chef. This handler serializes the run status data to a JSON file located at `/var/chef/reports`.\n\n## Unit Testing\nchef_handler provides built in [chefspec](https://github.com/sethvargo/chefspec) matchers for assisting unit tests. These matchers will only be loaded if chefspec is already loaded. Following is an example of asserting against the jsonfile handler:\n\n```ruby\n expect(runner).to enable_chef_handler(\"Chef::Handler::JsonFile\").with(\n source: \"chef/handler/json_file\",\n arguments: { :path => '/var/chef/reports'},\n supports: {:exception => true}\n )\n end\n```\n\n## License & Authors\n**Author:** Cookbook Engineering Team ([cookbooks@chef.io](mailto:cookbooks@chef.io))\n\n**Copyright:** 2011-2016, Chef Software, Inc.\n\n```\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```\n","maintainer":"Chef Software, Inc.","maintainer_email":"cookbooks@chef.io","license":"Apache 2.0","platforms":{},"dependencies":{},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{"chef_handler":"Deploys all handlers to the handler path early during the run.","chef_handler::json_file":"Enables Chef::Handler::JsonFile to serialize run status data to /var/chef/reports."}} \ No newline at end of file diff --git a/cookbooks/chef_handler/providers/default.rb b/cookbooks/chef_handler/providers/default.rb deleted file mode 100644 index 7da21b9..0000000 --- a/cookbooks/chef_handler/providers/default.rb +++ /dev/null @@ -1,76 +0,0 @@ -# -# Author:: Seth Chisamore -# Cookbook Name:: chef_handler -# Provider:: default -# -# Copyright:: 2011-2016, Chef Software, Inc -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -include ::ChefHandler::Helpers - -def whyrun_supported? - true -end - -# This action needs to find an rb file that presumably contains the indicated class in it and the -# load that file. It then instantiates that class by name and registers it as a handler. -action :enable do - class_name = new_resource.class_name - new_resource.supports.each do |type, enable| - next unless enable - converge_by("disable #{class_name} as a #{type} handler") do - unregister_handler(type, class_name) - end - end - - handler = nil - converge_by("load #{class_name} from #{new_resource.source}") do - require new_resource.source - _, klass = get_class(class_name) - handler = klass.send(:new, *collect_args(new_resource.arguments)) - end - - new_resource.supports.each do |type, enable| - next unless enable - converge_by("enable #{new_resource} as a #{type} handler") do - register_handler(type, handler) - end - end -end - -action :disable do - new_resource.supports.each_key do |type| - converge_by("disable #{new_resource} as a #{type} handler") do - unregister_handler(type, new_resource.class_name) - end - end -end - -def load_current_resource - @current_resource = Chef::Resource::ChefHandler.new(new_resource.name) - @current_resource.class_name(new_resource.class_name) - @current_resource.source(new_resource.source) - @current_resource -end - -private - -def collect_args(resource_args = []) - if resource_args.is_a? Array - resource_args - else - [resource_args] - end -end diff --git a/cookbooks/chef_handler/resources/default.rb b/cookbooks/chef_handler/resources/default.rb deleted file mode 100644 index 503113b..0000000 --- a/cookbooks/chef_handler/resources/default.rb +++ /dev/null @@ -1,39 +0,0 @@ -# -# Author:: Seth Chisamore -# Cookbook Name:: chef_handler -# Resource:: default -# -# Copyright:: 2011-2016, Chef Software, Inc -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -actions :enable, :disable - -state_attrs :arguments, - :class_name, - :source, - :supports - -attribute :class_name, kind_of: String, name_attribute: true -attribute :source, default: nil, kind_of: String -attribute :arguments, default: [] -attribute :supports, kind_of: Hash, default: { report: true, exception: true } - -# we have to set default for the supports attribute -# in initializer since it is a 'reserved' attribute name -def initialize(*args) - super - @action = :enable - @supports = { report: true, exception: true } -end diff --git a/cookbooks/database/.foodcritic b/cookbooks/database/.foodcritic new file mode 100644 index 0000000..4d92e2e --- /dev/null +++ b/cookbooks/database/.foodcritic @@ -0,0 +1 @@ +~FC023 diff --git a/cookbooks/database/.gitignore b/cookbooks/database/.gitignore deleted file mode 100644 index 2d3a156..0000000 --- a/cookbooks/database/.gitignore +++ /dev/null @@ -1,46 +0,0 @@ -*.gem -.zero-knife.rb -*.rbc -.bundle -.config -coverage -InstalledFiles -lib/bundler/man -pkg -rdoc -spec/reports -test/tmp -test/version_tmp -tmp -Gemfile.lock -_Store -*~ -*# -.#* -\#*# -.*.sw[a-z] -*.un~ -*.tmp -*.bk -*.bkup -.ruby-version -.ruby-gemset -.rvmrc - -# YARD artifacts -.yardoc -_yardoc -doc/ -.idea -.ruby-version - -#chef stuff -Berksfile.lock -.kitchen -.kitchen.local.yml -vendor/ -.coverage/ - -#vagrant stuff -.vagrant/ -.vagrant.d/ diff --git a/cookbooks/database/.kitchen.cloud.yml b/cookbooks/database/.kitchen.cloud.yml deleted file mode 100644 index 47ff814..0000000 --- a/cookbooks/database/.kitchen.cloud.yml +++ /dev/null @@ -1,182 +0,0 @@ -#<% require 'kitchen-sync' %> ---- -driver_config: - digitalocean_client_id: <%= ENV['DIGITAL_OCEAN_CLIENT_ID'] %> - google_client_email: <%= ENV['GOOGLE_CLIENT_EMAIL'] %> - google_key_location: <%= ENV['GOOGLE_KEY_LOCATION'] %> - google_project: <%= ENV['GOOGLE_PROJECT'] %> - joyent_username: <%= ENV['SDC_CLI_ACCOUNT'] %> - joyent_keyfile: <%= ENV['SDC_CLI_IDENTITY'] %> - joyent_keyname: <%= ENV['SDC_CLI_KEY_ID'] %> - joyent_url: <%= ENV['SDC_CLI_URL'] %> - aws_access_key_id: <%= ENV['AWS_ACCESS_KEY_ID'] %> - aws_secret_access_key: <%= ENV['AWS_SECRET_ACCESS_KEY'] %> - aws_ssh_key_id: <%= ENV['AWS_KEYPAIR_NAME'] %> - flavor_id: <%= ENV['EC2_FLAVOR_ID'] %> - availability_zone: <%= ENV['AWS_AVAILABILITY_ZONE'] %> - -provisioner: - name: chef_zero - # require_chef_omnibus: 11.16.8 - # require_chef_omnibus: 12.0.3 - require_chef_omnibus: latest - -platforms: -- name: centos-5.8 - driver_plugin: digital_ocean - driver_config: - size: 2gb - image: centos-5-8-x64 - region: <%= ENV['DIGITAL_OCEAN_REGION'] %> - ssh_key_ids: <%= ENV['DIGITAL_OCEAN_SSH_KEY_IDS'] %> - ssh_key: <%= ENV['DIGITAL_OCEAN_SSH_KEY_PATH'] %> - -- name: centos-6.5 - driver_plugin: digital_ocean - driver_config: - size: 2gb - image: centos-6-5-x64 - region: <%= ENV['DIGITAL_OCEAN_REGION'] %> - ssh_key_ids: <%= ENV['DIGITAL_OCEAN_SSH_KEY_IDS'] %> - ssh_key: <%= ENV['DIGITAL_OCEAN_SSH_KEY_PATH'] %> - -- name: centos-7.0 - driver_plugin: digital_ocean - driver_config: - size: 2gb - image: centos-7-0-x64 - region: <%= ENV['DIGITAL_OCEAN_REGION'] %> - ssh_key_ids: <%= ENV['DIGITAL_OCEAN_SSH_KEY_IDS'] %> - ssh_key: <%= ENV['DIGITAL_OCEAN_SSH_KEY_PATH'] %> - -- name: amazon-2014.09 - driver_plugin: ec2 - driver_config: - image_id: ami-9a6ed3f2 - username: ec2-user - ssh_key: <%= ENV['EC2_SSH_KEY_PATH'] %> - -- name: fedora-20 - driver_plugin: digital_ocean - driver_config: - size: 2gb - image: fedora-20-x64 - region: <%= ENV['DIGITAL_OCEAN_REGION'] %> - ssh_key_ids: <%= ENV['DIGITAL_OCEAN_SSH_KEY_IDS'] %> - ssh_key: <%= ENV['DIGITAL_OCEAN_SSH_KEY_PATH'] %> - -- name: suse-11.3 - driver_plugin: ec2 - driver_config: - image_id: ami-e8084981 - username: root - ssh_key: <%= ENV['EC2_SSH_KEY_PATH'] %> - -- name: debian-7.0 - driver_plugin: gce - driver_config: - image_name: debian-7-wheezy-v20131120 - zone: <%= ENV['GCE_ZONE'] %> - area: <%= ENV['GCE_AREA'] %> - network: <%= ENV['GCE_NETWORK'] %> - username: <%= ENV['GCE_USERNAME'] %> - public_key_path: <%= ENV['GCE_PUBLIC_KEY_PATH'] %> - ssh_key: <%= ENV['GCE_SSH_KEY_PATH'] %> - run_list: - - recipe[apt] - -- name: ubuntu-10.04 - driver_plugin: digital_ocean - driver_config: - size: 2gb - image: ubuntu-10-04-x64 - region: <%= ENV['DIGITAL_OCEAN_REGION'] %> - ssh_key_ids: <%= ENV['DIGITAL_OCEAN_SSH_KEY_IDS'] %> - ssh_key: <%= ENV['DIGITAL_OCEAN_SSH_KEY_PATH'] %> - run_list: - - recipe[apt] - -- name: ubuntu-12.04 - driver_plugin: digital_ocean - driver_config: - size: 2gb - image: ubuntu-12-04-x64 - region: <%= ENV['DIGITAL_OCEAN_REGION'] %> - ssh_key_ids: <%= ENV['DIGITAL_OCEAN_SSH_KEY_IDS'] %> - ssh_key: <%= ENV['DIGITAL_OCEAN_SSH_KEY_PATH'] %> - run_list: - - recipe[apt] - -- name: ubuntu-14.04 - driver_plugin: digital_ocean - driver_config: - size: 2gb - image: ubuntu-14-04-x64 - region: <%= ENV['DIGITAL_OCEAN_REGION'] %> - ssh_key_ids: <%= ENV['DIGITAL_OCEAN_SSH_KEY_IDS'] %> - ssh_key: <%= ENV['DIGITAL_OCEAN_SSH_KEY_PATH'] %> - run_list: - - recipe[apt] - -suites: - # - # database-test - # - - name: myclient50 - run_list: - - recipe[mysql_database_test] - attributes: - mysql: - version: '5.0' - includes: [ - 'centos-5.8' - ] - - - name: myclient51 - run_list: - - recipe[mysql_database_test] - attributes: - mysql: - version: '5.1' - includes: [ - 'centos-6.5', - 'ubuntu-10.04' - ] - - - name: myclient55 - run_list: - - recipe[mysql_database_test] - attributes: - mysql: - version: '5.5' - includes: [ - 'centos-6.5', - 'debian-7.0', - 'ubuntu-12.04', - 'ubuntu-14.04' - ] - - - name: myclient56 - run_list: - - recipe[mysql_database_test] - attributes: - mysql: - version: '5.6' - includes: [ - 'centos-5.8', - 'centos-6.5', - 'centos-7.0', - 'ubuntu-14.04' - ] - - - name: myclient57 - run_list: - - recipe[mysql_database_test] - attributes: - mysql: - version: '5.7' - includes: [ - 'centos-5.8', - 'centos-6.5', - 'centos-7.0' - ] diff --git a/cookbooks/database/.kitchen.yml b/cookbooks/database/.kitchen.yml deleted file mode 100644 index 7af544e..0000000 --- a/cookbooks/database/.kitchen.yml +++ /dev/null @@ -1,33 +0,0 @@ ---- -driver: - name: vagrant - -provisioner: - name: chef_zero - -platforms: - - name: centos-5.11 - - name: centos-6.7 - - name: centos-7.1 - - name: debian-7.8 - run_list: - - recipe[apt] - - name: debian-8.1 - run_list: - - recipe[apt] - - name: fedora-21 - - name: ubuntu-12.04 - run_list: - - recipe[apt] - - name: ubuntu-14.04 - run_list: - - recipe[apt] - -suites: - # - # database-test - # - - name: default - run_list: - - recipe[mysql_database_test] - - recipe[postgresql_database_test] diff --git a/cookbooks/database/.rubocop.yml b/cookbooks/database/.rubocop.yml deleted file mode 100644 index 4df4b44..0000000 --- a/cookbooks/database/.rubocop.yml +++ /dev/null @@ -1,35 +0,0 @@ -AllCops: - Exclude: - - vendor/**/* - - 'Guardfile' - -AlignParameters: - Enabled: false - -Encoding: - Enabled: false - -ClassLength: - Enabled: false - -MethodLength: - Enabled: false - -LineLength: - Enabled: false - -Documentation: - Enabled: false - -PerceivedComplexity: - Enabled: false - -CyclomaticComplexity: - Enabled: false - -Style/FileName: - Enabled: false - -Metrics/AbcSize: - Enabled: false - diff --git a/cookbooks/database/.travis.yml b/cookbooks/database/.travis.yml deleted file mode 100644 index c5dd1f0..0000000 --- a/cookbooks/database/.travis.yml +++ /dev/null @@ -1,12 +0,0 @@ -sudo: false -cache: bundler -language: ruby -bundler_args: --without kitchen_common kitchen_vagrant -rvm: - - 2.0 - - 2.1 - - 2.2 -script: - - bundle exec foodcritic -f any . - - bundle exec rubocop - - bundle exec rspec --color --format progress diff --git a/cookbooks/database/Berksfile b/cookbooks/database/Berksfile deleted file mode 100644 index 424aee1..0000000 --- a/cookbooks/database/Berksfile +++ /dev/null @@ -1,12 +0,0 @@ -source 'https://supermarket.chef.io' - -metadata - -group :integration do - cookbook 'apt' - cookbook 'selinux' - cookbook 'mysql2_chef_gem' -end - -cookbook 'mysql_database_test', path: 'test/fixtures/cookbooks/mysql_database_test' -cookbook 'postgresql_database_test', path: 'test/fixtures/cookbooks/postgresql_database_test' diff --git a/cookbooks/database/CHANGELOG.md b/cookbooks/database/CHANGELOG.md index bcb5c0d..f5053ad 100644 --- a/cookbooks/database/CHANGELOG.md +++ b/cookbooks/database/CHANGELOG.md @@ -1,8 +1,70 @@ -Database cookbook README -======================== +# Database cookbook CHANGELOG + +This file is used to list changes made in each version of the database cookbook. + +## 6.1.1 (2016-11-01) +- Fix incorrectly named matchers + +## 6.1.0 (2016-11-01) +- Add require_x509 option for mysql grants +- Define custom matcher helpers for notification testing, fixes #200 +- Add support for PostgreSQL extended grants +- Use multipackage to speed up the installs +- Remove arch from the metadata +- Improve specs +- Remove yum/apt in the Berksfile +- Add opensuse and opensuseleap to the metadata + +## 6.0.0 (2016-09-22) +- Update maintainers wording and format [skip-ci] +- Support reading of options from my.cnf for MySQL +- Fix hashed_password for CREATE USER +- Generalize MysqlPassword to HashedPassword and add it to PostreSQL +- Fix again undefined method `empty?' for Mysql2::Result +- Exclude the Rubocop rule that breaks the cookbook +- Require Chef 12.1 or later + +## v5.1.2 (2016-04-21) + +- Fix for Unknown column 'mysql_native_password' error +- Fix 'already initialized constant' warnings while testing + +## v5.1.1 (2016-04-07) + +- Fixed password resource not functioning on Postgresql +- Removed unused templates leftover from the DB -> EBS backup recipes +- Add better logging when the providers are used and the gems are not present + +## v5.1.0 (2016-04-06) + +- Added a new resource for Sqlite DBs. See the readme for details +- Updated :create and :grant action in the mysql_database_user provider to update the user password if it changes +- Added the ability to pass options to the sql_server connection +- Added a mysql_hashed_password method to the mysql_database_user's password property to allow passing hashed passwords to the resource. See the readme for an example + +## v5.0.1 (2016-03-29) + +- Resolve error in the user provider under MySQL due to a Rubocop fix + +## v5.0.0 (2016-03-23) + +- Removed Chef 10 compatibility checks +- Resolved the following error in the sql_server_user provider: undefined local variable or method `sql_role` +- Added a timeout attribute to the database provider on sql_server, which defaults to 120 seconds +- Fixed the :revoke action for the database_user provider on mysql +- Removed duplicate documentation from the readme +- Updated the mysql_user provider to compare passwords so passwords can be updated +- Updated documentation for the connection hash in the database provider +- Removed duplicate amazon supports property from the metadata +- Removed documentation for ebs recipes that are no longer part of this cookbook +- Updated testing deps and removed the large number of Guard deps +- Fixed intgration tests to be in the correct location so they run as expected +- Added .foodcritic file to ignore FC023 +- Removed the cloud testing Kitchen file and Gem dependencies +- Added integration testing with Kitchen Docker in Travis CI + +## v4.0.9 (2015-09-07) -v4.0.9 (2015-09-07) -------------------- - Fix bad attribute name with postgresql_database in the readme - Add `flags` attribute to the mysql provider - Add `database` attribute to the mysql provider @@ -20,147 +82,141 @@ v4.0.9 (2015-09-07) - Add a chefignore file - Update list of ignored files in the gitignore -v4.0.8 (2015-08-03) -------------------- -- #139 - Use a more reliable method of determining whether the - Postgres server accepts the REPLICATION attribute on user creation. +## v4.0.8 (2015-08-03) -v4.0.7 (2015-07-27) -------------------- -- #161 - Fixes multiple issues causing the MySQL database user creation to not be idempotent +- 139 - Use a more reliable method of determining whether the +- Postgres server accepts the REPLICATION attribute on user creation. -v4.0.6 (2015-04-29) -------------------- -- #126 - Use sql_query property instead of sql in the mysql provider for :query action +## v4.0.7 (2015-07-27) -v4.0.5 (2015-04-08) -------------------- -- #137/#138 - Removing log message containing password information +- 161 - Fixes multiple issues causing the MySQL database user creation to not be idempotent + +## v4.0.6 (2015-04-29) + +- 126 - Use sql_query property instead of sql in the mysql provider for :query action + +## v4.0.5 (2015-04-08) + +- 137/#138 - Removing log message containing password information + +## v4.0.4 (2015-04-07) -v4.0.4 (2015-04-07) -------------------- - Using unescaped db name in field value -v4.0.3 (2015-02-22) -------------------- +## v4.0.3 (2015-02-22) + - Unbreak postgresql_database_resource on older versions of PostgreSQL -v4.0.2 (2015-02-09) -------------------- +## v4.0.2 (2015-02-09) + - Removing leftover mysql recipe that installs the mysql2_chef_gem. -v4.0.1 (2015-02-05) -------------------- +## v4.0.1 (2015-02-05) + - Fixing merge conflicts with master on 4.0.0 attempted release -v4.0.0 (2015-02-05) -------------------- +## v4.0.0 (2015-02-05) + - Decoupled mysql2_chef_gem cookbook. - Users must now install it themselves before utilizing mysql_database - or mysql_database_user resources. +- Users must now install it themselves before utilizing mysql_database +- or mysql_database_user resources. - Fixing various MilClass errors in mysql providers - Restoring missing :query action for mysql - Restoring grant_option support for mysql - Adding revoke action for mysql -v3.1.0 (2015-01-30) -------------------- +## v3.1.0 (2015-01-30) + - Add support for postgresql_database_user privileges - Add postgresql_database_test cookbook to test/fixtures -v3.0.3 (2015-01-20) -------------------- +## v3.0.3 (2015-01-20) + - Bugfix: bugfix: lack of node['mysql']['version'] causing NilClass error -v3.0.2 (2015-01-16) -------------------- +## v3.0.2 (2015-01-16) + - Fix bug to allow grants on databases with special characters -v3.0.1 (2015-01-16) -------------------- +## v3.0.1 (2015-01-16) + - Enabling ssl for provider_mysql_database_user -v3.0.0 (2015-01-15) -------------------- +## v3.0.0 (2015-01-15) + - Removing out of scope recipes - porting to mysql2_chef_gem - adding test-kitchen suites for mysql -v2.3.1 (2014-12-13) -------------------- +## v2.3.1 (2014-12-13) + - Locking mysql and mysql-chef_gem dependencies down in metadata.rb -v2.3.0 (2014-08-13) -------------------- +## v2.3.0 (2014-08-13) + - [#62] Allow requiring SSL +## v2.2.0 (2014-05-07) -v2.2.0 (2014-05-07) -------------------- - [COOK-4626] Add windows users for SQL Server - [COOK-4627] Assigning sys_roles in SQL Server +## v2.1.10 (2014-05-07) -v2.1.10 (2014-05-07) --------------------- - [COOK-4614] - Update README to reflect gem installation via mysql-chef_gem +## v2.1.8 (2014-04-23) -v2.1.8 (2014-04-23) -------------------- - [COOK-4583] - Add ChefSpec matchers +## v2.1.6 (2014-04-10) -v2.1.6 (2014-04-10) -------------------- - [COOK-4538] Bump supported Chef version +## v2.1.4 (2014-04-09) -v2.1.4 (2014-04-09) -------------------- [COOK-4529] Query action ignores MySQL errors +## v2.1.2 (2014-04-01) -v2.1.2 (2014-04-01) -------------------- - Depending on mysql-chef_gem cookbook +## v2.1.0 (2014-03-31) -v2.1.0 (2014-03-31) -------------------- - Updating mysql cookbook dependency - Enforcing rubocops +## v2.0.0 (2014-02-25) -v2.0.0 (2014-02-25) -------------------- [COOK-3441] database_user password argument should not be required +## v1.6.0 -v1.6.0 ------- ### New Feature + - **[COOK-4009](https://tickets.chef.io/browse/COOK-4009)** - Add PostgreSQL SCHEMA management capability ### Improvement + - **[COOK-3862](https://tickets.chef.io/browse/COOK-3862)** - Improve database cookbook documentation +## v1.5.2 -v1.5.2 ------- ### Improvement + - **[COOK-3716](https://tickets.chef.io/browse/COOK-3716)** - Add ALTER SQL Server user roles +## v1.5.0 -v1.5.0 ------- ### Improvement + - **[COOK-3546](https://tickets.chef.io/browse/COOK-3546)** - Add connection parameters `:socket` - **[COOK-1709](https://tickets.chef.io/browse/COOK-1709)** - Add 'grant_option' parameter -v1.4.0 -------- +## v1.4.0 + ### Bug + - [COOK-2074]: Regex in exists? check in `sql_server_database` resource should match for start and end of line - [COOK-2561]: `mysql_database_user` can't set global grants @@ -168,68 +224,68 @@ v1.4.0 - [COOK-2075]: Support the collation attribute in the `database_sql_server` provider -v1.3.12 -------- +## v1.3.12 + - [COOK-850] - `postgresql_database_user` doesn't have example -v1.3.10 -------- +## v1.3.10 + - [COOK-2117] - undefined variable `grant_statement` in mysql user provider -v1.3.8 ------- +## v1.3.8 + - [COOK-1896] - Escape command - [COOK-2047] - Chef::Provider::Database::MysqlUser action :grant improperly quotes `username`@`host` string -- [COOK-2060] - Mysql::Error: Table '*.*' doesn't exist when privileges include SELECT and database/table attributes are nil +- [COOK-2060] - Mysql::Error: Table '_._' doesn't exist when privileges include SELECT and database/table attributes are nil - [COOK-2062] - Remove backticks from database name when using wildcard -v1.3.6 ------- +## v1.3.6 + - [COOK-1688] - fix typo in readme and add amazon linux to supported platforms -v1.3.4 ------- +## v1.3.4 + - [COOK-1561] - depend on mysql 1.3.0+ explicitly - depend on postgresql 1.0.0 explicitly -v1.3.2 ------- +## v1.3.2 + - Update the version for release (oops) -v1.3.0 ------- +## v1.3.0 + - [COOK-932] - Add mysql recipe to conveniently include mysql::ruby - [COOK-1228] - database resource should be able to execute scripts on disk - [COOK-1291] - make the snapshot retention policy less confusing - [COOK-1401] - Allow to specify the collation of new databases - [COOK-1534] - Add postgresql recipe to conveniently include postgresql::ruby -v1.2.0 ------- +## v1.2.0 + - [COOK-970] - workaround for disk [re]naming on ubuntu 11.04+ - [COOK-1085] - check RUBY_VERSION and act accordingly for role - [COOK-749] - localhost should be a string in snapshot recipe -v1.1.4 ------- +## v1.1.4 + - [COOK-1062] - Databases: Postgres exists should close connection -v1.1.2 ------- +## v1.1.2 + - [COOK-975] - Change arg='DEFAULT' to arg=nil, :default => 'DEFAULT' - [COOK-964] - Add parentheses around connection hash in example -v1.1.0 ------- +## v1.1.0 + - [COOK-716] - providers for PostgreSQL -v1.0.0 ------- +## v1.0.0 + - [COOK-683] - added `database` and `database_user` resources - [COOK-684] - MySQL providers - [COOK-685] - SQL Server providers - refactored - `database::master` and `database::snapshot` recipes to leverage new resources -v0.99.1 -------- +## v0.99.1 + - Use Chef 0.10's `node.chef_environment` instead of `node['app_environment']`. diff --git a/cookbooks/database/Gemfile b/cookbooks/database/Gemfile deleted file mode 100644 index 34f3aa0..0000000 --- a/cookbooks/database/Gemfile +++ /dev/null @@ -1,41 +0,0 @@ -source 'https://rubygems.org' - -group :lint do - gem 'foodcritic', '~> 4.0' - gem 'rubocop', '~> 0.33' - gem 'rainbow', '< 2.0' -end - -group :unit do - gem 'berkshelf', '~> 3.2' - gem 'chefspec', '~> 4.3' -end - -group :kitchen_common do - gem 'test-kitchen', '~> 1.4' -end - -group :kitchen_vagrant do - gem 'kitchen-vagrant', '~> 0.18' -end - -group :kitchen_cloud do - gem 'kitchen-digitalocean' - gem 'kitchen-ec2' - gem 'kitchen-joyent' - gem 'kitchen-gce' -end - -group :development do - gem 'ruby_gntp' - gem 'growl' - gem 'rb-fsevent' - gem 'guard', '~> 2.4' - gem 'guard-kitchen' - gem 'guard-foodcritic' - gem 'guard-rspec' - gem 'guard-rubocop' - gem 'rake' - gem 'fauxhai' - gem 'pry-nav' -end diff --git a/cookbooks/database/Guardfile b/cookbooks/database/Guardfile deleted file mode 100644 index 5b8e7dc..0000000 --- a/cookbooks/database/Guardfile +++ /dev/null @@ -1,24 +0,0 @@ -# More info at https://github.com/guard/guard#readme - -guard 'foodcritic', :cookbook_paths => '.', :cli => '-t ~FC023 -t ~FC005', :all_on_start => false do - watch(/attributes\/.+\.rb$/) - watch(/providers\/.+\.rb$/) - watch(/recipes\/.+\.rb$/) - watch(/resources\/.+\.rb$/) - watch('metadata.rb') -end - -guard 'rubocop' do - watch(/attributes\/.+\.rb$/) - watch(/providers\/.+\.rb$/) - watch(/recipes\/.+\.rb$/) - watch(/resources\/.+\.rb$/) - watch('metadata.rb') -end - -guard :rspec, :cmd => 'chef exec /opt/chefdk/embedded/bin/rspec', :all_on_start => false, :notification => false do - watch(/^libraries\/(.+)\.rb$/) - watch(/^spec\/(.+)_spec\.rb$/) - watch(/^(recipes)\/(.+)\.rb$/) { |m| "spec/#{m[1]}_spec.rb" } - watch('spec/spec_helper.rb') { 'spec' } -end diff --git a/cookbooks/database/LICENSE b/cookbooks/database/LICENSE deleted file mode 100644 index 1b91cbb..0000000 --- a/cookbooks/database/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - -Copyright 2008-2015 Chef Software Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/cookbooks/database/MAINTAINERS.md b/cookbooks/database/MAINTAINERS.md index c6a51ae..645ed14 100644 --- a/cookbooks/database/MAINTAINERS.md +++ b/cookbooks/database/MAINTAINERS.md @@ -1,19 +1,15 @@ # Maintainers -This file lists how this cookbook project is maintained. When making changes to the system, this -file tells you who needs to review your patch - you need a simple majority of maintainers -for the relevant subsystems to provide a :+1: on your pull request. Additionally, you need -to not receive a veto from a Lieutenant or the Project Lead. -Check out [How Cookbooks are Maintained](https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/CONTRIBUTING.MD) -for details on the process and how to become a maintainer or the project lead. +This file lists how this cookbook project is maintained. When making changes to the system, this file tells you who needs to review your patch - you need a review from an existing maintainer for the cookbook to provide a :+1: on your pull request. Additionally, you need to not receive a veto from a Lieutenant or the Project Lead. + +Check out [How Cookbooks are Maintained](https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/CONTRIBUTING.MD) for details on the process and how to become a maintainer or the project lead. # Project Maintainer * [Tim Smith](https://github.com/tas50) # Maintainers * [Jennifer Davis](https://github.com/sigje) -* [Sean OMeara](https://github.com/someara) * [Tim Smith](https://github.com/tas50) * [Thom May](https://github.com/thommay) diff --git a/cookbooks/database/MAINTAINERS.toml b/cookbooks/database/MAINTAINERS.toml deleted file mode 100644 index 47778d6..0000000 --- a/cookbooks/database/MAINTAINERS.toml +++ /dev/null @@ -1,46 +0,0 @@ -# -# This file is structured to be consumed by both humans and computers. -# It is a TOML document containing Markdown -# -[Preamble] - title = "Maintainers" - text = """ -This file lists how this cookbook project is maintained. When making changes to the system, this -file tells you who needs to review your patch - you need a simple majority of maintainers -for the relevant subsystems to provide a :+1: on your pull request. Additionally, you need -to not receive a veto from a Lieutenant or the Project Lead. - -Check out [How Cookbooks are Maintained](https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/CONTRIBUTING.MD) -for details on the process and how to become a maintainer or the project lead. -""" - -[Org] - [Org.Components] - [Org.Components.Core] - title = "Project Maintainer" - - lieutenant = 'tas50' - - maintainers = [ - 'sigje', - 'someara', - 'tas50', - 'thommay' - ] - -[people] - [people.sigje] - name = "Jennifer Davis" - github = "sigje" - - [people.someara] - name = "Sean OMeara" - github = "someara" - - [people.tas50] - name = "Tim Smith" - github = "tas50" - - [people.thommay] - name = "Thom May" - github = "thommay" diff --git a/cookbooks/database/README.md b/cookbooks/database/README.md index 6da5bbd..6f3a17a 100644 --- a/cookbooks/database/README.md +++ b/cookbooks/database/README.md @@ -1,93 +1,78 @@ -Database Cookbook -================= -[![Build Status](https://travis-ci.org/opscode-cookbooks/database.svg?branch=master)](http://travis-ci.org/opscode-cookbooks/database) -[![Cookbook Version](https://img.shields.io/cookbook/v/database.svg)](https://supermarket.chef.io/cookbooks/database) +# Database Cookbook -The main highlight of this cookbook is the `database` and -`database_user` resources for managing databases and database users in -a RDBMS. Providers for MySQL, PostgreSQL and SQL Server are also -provided, see usage documentation below. +[![Build Status](https://travis-ci.org/chef-cookbooks/database.svg?branch=master)](http://travis-ci.org/chef-cookbooks/database) [![Cookbook Version](http://img.shields.io/cookbook/v/database.svg)](https://supermarket.chef.io/cookbooks/database) + +The main highlight of this cookbook is the `database` and `database_user` resources for managing databases and database users in a RDBMS. Providers for MySQL, PostgreSQL and SQL Server are also provided, see usage documentation below. + +## Requirements -Requirements ------------- ### Platforms + - Debian / Ubuntu derivatives - RHEL derivatives - Fedora ### Chef -- Chef 11+ + +- Chef 12.1+ ### Cookbooks -The following Chef Software cookbooks are dependencies: -* postgresql +- postgresql -Resources/Providers -------------------- -These resources aim to expose an abstraction layer for interacting -with different RDBMS in a general way. Currently the cookbook ships -with providers for MySQL, PostgreSQL and SQL Server. Please see -specific usage in the __Example__ sections below. The providers use -specific Ruby gems installed under Chef's Ruby environment to execute -commands and carry out actions. These gems will need to be installed -before the providers can operate correctly. Specific notes for each -RDBS flavor: +## Resources/Providers -- MySQL: leverages the `mysql2` gem, which can be installed with the - `mysql2_chef_gem` resource prior to use (available on the - Supermarket). You must depend on the `mysql2_chef_gem` cookbook, - then use a `mysql2_chef_gem` resource to install it. The resource - allows the user to select MySQL client library versions, as well as - optionally select MariaDB libraries. - -- PostgreSQL: leverages the `pg` gem which is installed as part of the - `postgresql::ruby` recipe. You must declare `include_recipe - "database::postgresql"` to include this. +These resources aim to expose an abstraction layer for interacting with different RDBMS in a general way. Currently the cookbook ships with providers for MySQL, PostgreSQL and SQL Server. Please see specific usage in the **Example** sections below. The providers use specific Ruby gems installed under Chef's Ruby environment to execute commands and carry out actions. These gems will need to be installed before the providers can operate correctly. Specific notes for each RDBS flavor: -- SQL Server: leverages the `tiny_tds` gem which is installed as part - of the `sql_server::client` recipe. +- MySQL: leverages the `mysql2` gem, which can be installed with the `mysql2_chef_gem` resource prior to use (available on the Supermarket). You must depend on the `mysql2_chef_gem` cookbook, then use a `mysql2_chef_gem` resource to install it. The resource allows the user to select MySQL client library versions, as well as optionally select MariaDB libraries. + +- PostgreSQL: leverages the `pg` gem which is installed as part of the `postgresql::ruby` recipe. You must declare `include_recipe "database::postgresql"` to include this. + +- SQL Server: leverages the `tiny_tds` gem which is installed as part of the `sql_server::client` recipe. + +- SQLite: leverages the `sqlite3` gem which is installed as part of the `database::sqlite` recipe. You must declare `include_recipe "database::sqlite"` to include this. ### database -Manage databases in a RDBMS. Use the proper shortcut resource -depending on your RDBMS: `mysql_database`, `postgresql_database` or -`sql_server_database`. + +Manage databases in a RDBMS. Use the proper shortcut resource depending on your RDBMS: `mysql_database`, `postgresql_database`, `sql_server_database` or `sqlite_database`. #### Actions -- :create: create a named database -- :drop: drop a named database -- :query: execute an arbitrary query against a named database + +- `:create`: create a named database +- `:drop`: drop a named database +- `:query`: execute an arbitrary query against a named database #### Attribute Parameters + - database_name: name attribute. Name of the database to interact with -- connection: hash of connection info. valid keys include `:host`, - `:port`, `:username`, and `:password` (only for MySQL DB*) +- connection: hash of connection info. valid keys include `:host`, `:port`, `:username`, and `:password` -- sql: string of sql or a block that executes to a string of sql, - which will be executed against the database. used by `:query` action - only + - only for MySQL DB*: -\* The database cookbook uses the `mysql2` gem. + - `:flags` (see `Mysql2::Client@@default_query_options[:connect_flags]`) + - `:default_file`, `:default_group` (see ) -> "The value of host may be either a host name or an IP address. If - host is NULL or the string "127.0.0.1", a connection to the local - host is assumed. For Windows, the client connects using a - shared-memory connection, if the server has shared-memory - connections enabled. Otherwise, TCP/IP is used. For a host value of - "." on Windows, the client connects using a named pipe, if the - server has named-pipe connections enabled. If named-pipe connections - are not enabled, an error occurs." + - only for PostgreSQL: `:database` (overwrites parameter `database_name`) -If you specify a `:socket` key and are using the mysql_service -resource to set up the MySQL service, you'll need to specify the path -in the form `/var/run/mysql-/mysqld.sock`. + - not used for SQLlite + +- sql: string of sql or a block that executes to a string of sql, which will be executed against the database. used by `:query` action only + +- The database cookbook uses the `mysql2` gem. + +> "The value of host may be either a host name or an IP address. If host is NULL or the string "127.0.0.1", a connection to the local host is assumed. For Windows, the client connects using a shared-memory connection, if the server has shared-memory connections enabled. Otherwise, TCP/IP is used. For a host value of "." on Windows, the client connects using a named pipe, if the server has named-pipe connections enabled. If named-pipe connections are not enabled, an error occurs." + +If you specify a `:socket` key and are using the mysql_service resource to set up the MySQL service, you'll need to specify the path in the form `/var/run/mysql-/mysqld.sock`. #### Providers + - `Chef::Provider::Database::Mysql`: shortcut resource `mysql_database` - `Chef::Provider::Database::Postgresql`: shortcut resource `postgresql_database` - `Chef::Provider::Database::SqlServer`: shortcut resource `sql_server_database` +- `Chef::Provider::Database::Sqlite`: shortcut resource `sqlite_database` #### Examples + ```ruby # Create a mysql database mysql_database 'wordpress-cust01' do @@ -99,6 +84,7 @@ mysql_database 'wordpress-cust01' do action :create end ``` + ```ruby # Create a mysql database on a named mysql instance mysql_database 'oracle_rools' do @@ -109,8 +95,9 @@ mysql_database 'oracle_rools' do :password => node['mysql']['server_root_password'] ) action :create -end +end ``` + ```ruby # Create a sql server database sql_server_database 'mr_softie' do @@ -118,7 +105,8 @@ sql_server_database 'mr_softie' do :host => '127.0.0.1', :port => node['sql_server']['port'], :username => 'sa', - :password => node['sql_server']['server_sa_password'] + :password => node['sql_server']['server_sa_password'], + :options => { 'ANSI_NULLS' => 'ON', 'QUOTED_IDENTIFIER' => 'OFF' } ) action :create end @@ -248,139 +236,46 @@ postgresql_database 'vacuum databases' do end ``` +```ruby +# Create, Insert, Query a SQLite database +# Note that inserting anything in to the database will create it automaticly. +sqlite_database 'mr_softie' do + database_name '/path/to/database.db3' + sql "sql command" + action :query +end + +# Delete the database, will remove the file +sqlite_database 'mr_softie' do + database_name '/path/to/database.db3' + action :drop +end +``` + ### database_user + Manage users and user privileges in a RDBMS. Use the proper shortcut resource depending on your RDBMS: `mysql_database_user`, `postgresql_database_user`, or `sql_server_database_user`. #### Actions -- :create: create a user -- :drop: drop a user -- :grant: manipulate user privileges on database objects + +- `:create`: create a user +- `:drop`: drop a user +- `:grant`: manipulate user privileges on database objects #### Attribute Parameters + - username: name attribute. Name of the database user - password: password for the user account - database_name: Name of the database to interact with -- connection: hash of connection info. valid keys include :host, - :port, :username, :password -- privileges: array of database privileges to grant user. used by the - :grant action. default is :all -- host: host where user connections are allowed from. used by MySQL - provider only. default is '127.0.0.1' -- table: table to grant privileges on. used by :grant action and MySQL - provider only. default is '*' (all tables) +- connection: hash of connection info. valid keys include :host, :port, :username, :password +- privileges: array of database privileges to grant user. used by the :grant action. default is :all +- host: host where user connections are allowed from. used by MySQL provider only. default is '127.0.0.1' +- table: table to grant privileges on. used by :grant action and MySQL provider only. default is '*' (all tables) - require_ssl: true or false to force SSL connections to be used for user - -### Providers - -- **Chef::Provider::Database::MysqlUser**: shortcut resource - `mysql_database_user` -- **Chef::Provider::Database::PostgresqlUser**: shortcut - resource `postgresql_database_user` -- **Chef::Provider::Database::SqlServerUser**: shortcut resource - `sql_server_database_user` - -### Examples - - # create connection info as an external ruby hash - mysql_connection_info = {:host => "127.0.0.1", - :username => 'root', - :password => node['mysql']['server_root_password']} - postgresql_connection_info = {:host => "127.0.0.1", - :port => node['postgresql']['config']['port'], - :username => 'postgres', - :password => node['postgresql']['password']['postgres']} - sql_server_connection_info = {:host => "127.0.0.1", - :port => node['sql_server']['port'], - :username => 'sa', - :password => node['sql_server']['server_sa_password']} - - # create a mysql user but grant no privileges - mysql_database_user 'disenfranchised' do - connection mysql_connection_info - password 'super_secret' - action :create - end - - # do the same but pass the provider to the database resource - database_user 'disenfranchised' do - connection mysql_connection_info - password 'super_secret' - provider Chef::Provider::Database::MysqlUser - action :create - end - - # create a postgresql user but grant no privileges - postgresql_database_user 'disenfranchised' do - connection postgresql_connection_info - password 'super_secret' - action :create - end - - # do the same but pass the provider to the database resource - database_user 'disenfranchised' do - connection postgresql_connection_info - password 'super_secret' - provider Chef::Provider::Database::PostgresqlUser - action :create - end - - # create a sql server user but grant no privileges - sql_server_database_user 'disenfranchised' do - connection sql_server_connection_info - password 'super_secret' - action :create - end - - # drop a mysql user - mysql_database_user "foo_user" do - connection mysql_connection_info - action :drop - end - - # bulk drop sql server users - %w{ disenfranchised foo_user }.each do |user| - sql_server_database_user user do - connection sql_server_connection_info - action :drop - end - end - - # grant select,update,insert privileges to all tables in foo db from all hosts, requiring connections over SSL - mysql_database_user 'foo_user' do - connection mysql_connection_info - password 'super_secret' - database_name 'foo' - host '%' - privileges [:select,:update,:insert] - require_ssl true - action :grant - end - - # grant all privileges on all databases/tables from 127.0.0.1 - mysql_database_user 'super_user' do - connection mysql_connection_info - password 'super_secret' - action :grant - end - - # grant all privileges on all tables in foo db - postgresql_database_user 'foo_user' do - connection postgresql_connection_info - database_name 'foo' - privileges [:all] - action :grant - end - - # grant select,update,insert privileges to all tables in foo db - sql_server_database_user 'foo_user' do - connection sql_server_connection_info - password 'super_secret' - database_name 'foo' - privileges [:select,:update,:insert] - action :grant - end +- require_x509: true or false to force SSL with client certificate verification #### Providers + - `Chef::Provider::Database::MysqlUser`: shortcut resource `mysql_database_user` - `Chef::Provider::Database::PostgresqlUser`: shortcut resource `postgresql_database_user` - `Chef::Provider::Database::SqlServerUser`: shortcut resource`sql_server_database_user` @@ -409,8 +304,6 @@ sql_server_connection_info = { :password => node['sql_server']['server_sa_password'] } - - # Create a mysql user but grant no privileges mysql_database_user 'disenfranchised' do connection mysql_connection_info @@ -418,8 +311,6 @@ mysql_database_user 'disenfranchised' do action :create end - - # Do the same but pass the provider to the database resource database_user 'disenfranchised' do connection mysql_connection_info @@ -428,8 +319,6 @@ database_user 'disenfranchised' do action :create end - - # Create a postgresql user but grant no privileges postgresql_database_user 'disenfranchised' do connection postgresql_connection_info @@ -437,7 +326,13 @@ postgresql_database_user 'disenfranchised' do action :create end - +# The same as above but utilizing hashed password string instead of +# plain text one +postgresql_database_user 'disenfranchised' do + connection postgresql_connection_info + password hashed_password('md5eacdbf8d9847a76978bd515fae200a2a') + action :grant +end # Do the same but pass the provider to the database resource database_user 'disenfranchised' do @@ -447,8 +342,6 @@ database_user 'disenfranchised' do action :create end - - # Create a sql server user but grant no privileges sql_server_database_user 'disenfranchised' do connection sql_server_connection_info @@ -456,16 +349,12 @@ sql_server_database_user 'disenfranchised' do action :create end - - # Drop a mysql user mysql_database_user 'foo_user' do connection mysql_connection_info action :drop end - - # Bulk drop sql server users %w(disenfranchised foo_user).each do |user| sql_server_database_user user do @@ -474,8 +363,6 @@ end end end - - # Grant SELECT, UPDATE, and INSERT privileges to all tables in foo db from all hosts mysql_database_user 'foo_user' do connection mysql_connection_info @@ -486,7 +373,16 @@ mysql_database_user 'foo_user' do action :grant end - +# The same as above but utilizing hashed password string instead of +# plain text one +mysql_database_user 'foo_user' do + connection mysql_connection_info + password hashed_password('*664E8D709A6EBADFC68361EBE82CF77F10211E52') + database_name 'foo' + host '%' + privileges [:select,:update,:insert] + action :grant +end # Grant all privileges on all databases/tables from 127.0.0.1 mysql_database_user 'super_user' do @@ -495,14 +391,16 @@ mysql_database_user 'super_user' do action :grant end - - -# Grant all privileges on all tables in foo db +# grant all privileges on all tables, sequences and functions in public schema of foo db postgresql_database_user 'foo_user' do connection postgresql_connection_info database_name 'foo' + schema_name 'public' + tables [:all] + sequences [:all] + functions [:all] privileges [:all] - action :grant + action [:grant, :grant_schema, :grant_table, :grant_sequence, :grant_function] end # grant select,update,insert privileges to all tables in foo db @@ -515,129 +413,13 @@ sql_server_database_user 'foo_user' do end ``` +## License & Authors -Recipes -------- -### ebs_volume -*Note*: This recipe does not currently work on RHEL platforms due to the xfs cookbook not supporting RHEL yet. +**Author:** Cookbook Engineering Team ([cookbooks@chef.io](mailto:cookbooks@chef.io)) -Loads the aws information from the data bag. Searches the applications data bag for the database master or slave role and checks that role is applied to the node. Loads the EBS information and the master information from data bags. Uses the aws cookbook LWRP, `aws_ebs_volume` to manage the volume. +**Copyright:** 2009-2016, Chef Software, Inc. -On a master node: -- if we have an ebs volume already as stored in a data bag, attach it -- if we don't have the ebs information then create a new one and attach it -- store the volume information in a data bag via a ruby block - -On a slave node: -- use the master volume information to generate a snapshot -- create the new volume from the snapshot and attach it - -Also on a master node, generate some configuration for running a snapshot via `chef-solo` from cron. - -On a new filesystem volume, create as XFS, then mount it in `/mnt`, and also bind-mount it to the mysql data directory (default `/var/lib/mysql`). - -### master -This recipe no longer loads AWS specific information, and the database position for replication is no longer stored in a databag because the client might not have permission to write to the databag item. This may be handled in a different way at a future date. - -Searches the apps databag for applications, and for each one it will check that the specified database master role is set in both the databag and applied to the node's run list. Then, retrieves the passwords for `root`, `repl` and `debian` users and saves them to the node attributes. If the passwords are not found in the databag, it prints a message that they'll be generated by the mysql cookbook. - -Then it adds the application databag database settings to a hash, to use later. - -Then it will iterate over the databases and create them with the `mysql_database` resource while adding privileges for application specific database users using the `mysql_database_user` resource. - -### slave -_TODO_: Retrieve the master status from a data bag, then start replication using a ruby block. The replication status needs to be handled in some other way for now since the master recipe above doesn't actually set it in the databag anymore. - -### snapshot -Run via Chef Solo. Retrieves the db snapshot configuration from the specified JSON file. Uses the `mysql_database` resource to lock and unlock tables, and does a filesystem freeze and EBS snapshot. - - -Deprecated Recipes ------------------- -The following recipe is considered deprecated. It is kept for reference purposes. - -### ebs_backup -Older style of doing mysql snapshot and replication using Adam Jacob's [ec2_mysql](http://github.com/adamhjk/ec2_mysql) script and library. - - -Data Bags ---------- -This cookbook uses the apps data bag item for the specified application; see the `application` cookbook's README.md. It also creates data bag items in a bag named 'aws' for storing volume information. In order to interact with EC2, it expects aws to have a main item: - -```javascript -{ - "id": "main", - "ec2_private_key": "private key as a string", - "ec2_cert": "certificate as a string", - "aws_account_id": "", - "aws_secret_access_key": "", - "aws_access_key_id": "" -} ``` - -Note: with the Open Source Chef Server, the server using the database recipes must be an admin client or it will not be able to create data bag items. You can modify whether the client is admin by editing it with knife. - - knife client edit - { - ... - "admin": true - ... - } - -This is not required if the Chef Server is Chef Software Hosted Chef, instead use the ACL feature to modify access for the node to be able to update the data bag. - - -Usage ------ -Aside from the application data bag (see the README in the application cookbook), create a role for the database master. Use a `role.rb` in your chef-repo, or create the role directly with knife. - -```javascript -{ - "name": "my_app_database_master", - "chef_type": "role", - "json_class": "Chef::Role", - "default_attributes": {}, - "description": "", - "run_list": [ - "recipe[mysql::server]", - "recipe[database::master]" - ], - "override_attributes": {} -} -``` - -Create a `production` environment. This is also used in the `application` cookbook. - -```javascript -{ - "name": "production", - "description": "", - "cookbook_versions": {}, - "json_class": "Chef::Environment", - "chef_type": "environment", - "default_attributes": {}, - "override_attributes": {} -} -``` - -The cookbook `my_app_database` is recommended to set up any -application specific database resources such as configuration -templates, trending monitors, etc. It is not required, but you would -need to create it separately in `site-cookbooks`. Add it to the -`my_app_database_master` role. - -License & Authors ------------------ -- Author:: Adam Jacob () -- Author:: Joshua Timberman () -- Author:: AJ Christensen () -- Author:: Seth Chisamore () -- Author:: Lamont Granquist () -- Author:: Sean OMeara () - -```text -Copyright 2009-2015, Chef Software, Inc. - Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at diff --git a/cookbooks/database/Rakefile b/cookbooks/database/Rakefile deleted file mode 100644 index 3c52bbb..0000000 --- a/cookbooks/database/Rakefile +++ /dev/null @@ -1,61 +0,0 @@ -require 'rspec/core/rake_task' -require 'rubocop/rake_task' -require 'foodcritic' -require 'kitchen' - -require_relative 'tasks/maintainers' - -# Style tests. Rubocop and Foodcritic -namespace :style do - desc 'Run Ruby style checks' - RuboCop::RakeTask.new(:ruby) - - desc 'Run Chef style checks' - FoodCritic::Rake::LintTask.new(:chef) do |t| - t.options = { - fail_tags: ['any'], - tags: ['~FC005'] - } - end -end - -desc 'Run all style checks' -task style: ['style:chef', 'style:ruby'] - -# Rspec and ChefSpec -desc 'Run ChefSpec examples' -RSpec::Core::RakeTask.new(:spec) - -# Integration tests. Kitchen.ci -namespace :integration do - desc 'Run Test Kitchen with Vagrant' - task :vagrant do - Kitchen.logger = Kitchen.default_file_logger - Kitchen::Config.new.instances.each do |instance| - instance.test(:always) - end - end - - desc 'Run Test Kitchen with cloud plugins' - task :cloud do - run_kitchen = true - if ENV['TRAVIS'] == 'true' && ENV['TRAVIS_PULL_REQUEST'] != 'false' - run_kitchen = false - end - - if run_kitchen - Kitchen.logger = Kitchen.default_file_logger - @loader = Kitchen::Loader::YAML.new(project_config: './.kitchen.cloud.yml') - config = Kitchen::Config.new(loader: @loader) - config.instances.each do |instance| - instance.test(:always) - end - end - end -end - -desc 'Run all tests on Travis' -task travis: ['style', 'spec', 'integration:cloud'] - -# Default -task default: ['style', 'spec', 'integration:vagrant'] diff --git a/cookbooks/database/chefignore b/cookbooks/database/chefignore deleted file mode 100644 index e403950..0000000 --- a/cookbooks/database/chefignore +++ /dev/null @@ -1,100 +0,0 @@ -# Put files/directories that should be ignored in this file when uploading -# or sharing to the community site. -# Lines that start with '# ' are comments. - -# OS generated files # -###################### -.DS_Store -Icon? -nohup.out -ehthumbs.db -Thumbs.db - -# SASS # -######## -.sass-cache - -# EDITORS # -########### -\#* -.#* -*~ -*.sw[a-z] -*.bak -REVISION -TAGS* -tmtags -*_flymake.* -*_flymake -*.tmproj -.project -.settings -mkmf.log - -## COMPILED ## -############## -a.out -*.o -*.pyc -*.so -*.com -*.class -*.dll -*.exe -*/rdoc/ - -# Testing # -########### -.watchr -.rspec -spec/* -spec/fixtures/* -test/* -features/* -examples/* -Guardfile -Procfile - -# SCM # -####### -.git -*/.git -.gitignore -.gitmodules -.gitconfig -.gitattributes -.svn -*/.bzr/* -*/.hg/* -*/.svn/* - -# Berkshelf # -############# -Berksfile -Berksfile.lock -cookbooks/* -tmp - -# Cookbooks # -############# -CONTRIBUTING -CHANGELOG* - -# Strainer # -############ -Colanderfile -Strainerfile -.colander -.strainer - -# Vagrant # -########### -.vagrant -Vagrantfile - -# Travis # -########## -.travis.yml -test/ -spec/ -examples/ diff --git a/cookbooks/database/libraries/hashed_password.rb b/cookbooks/database/libraries/hashed_password.rb new file mode 100644 index 0000000..289f5c0 --- /dev/null +++ b/cookbooks/database/libraries/hashed_password.rb @@ -0,0 +1,50 @@ +# +# Author:: Maksim Horbul () +# Cookbook Name:: database +# Library:: hashed_password +# +# Copyright:: 2016 Eligible, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require File.join(File.dirname(__FILE__), 'resource_mysql_database_user') +require File.join(File.dirname(__FILE__), 'resource_postgresql_database_user') + +class HashedPassword + # Initializes an object of the MysqlPassword type + # @param [String] hashed_password mysql native hashed password + # @return [MysqlPassword] + def initialize(hashed_password) + @hashed_password = hashed_password + end + + # String representation of the object + # @return [String] hashed password string + def to_s + @hashed_password + end + + module Helpers + # helper method wrappers the string into a MysqlPassword object + # @param [String] hashed_password mysql native hashed password + # @return [MysqlPassword] object + def hashed_password(hashed_password) + HashedPassword.new hashed_password + end + # For backward compatibility, because method was renamed + alias_method :mysql_hashed_password, :hashed_password + end +end + +::Chef::Resource::MysqlDatabaseUser.send(:include, HashedPassword::Helpers) +::Chef::Resource::PostgresqlDatabaseUser.send(:include, HashedPassword::Helpers) diff --git a/cookbooks/database/libraries/matchers.rb b/cookbooks/database/libraries/matchers.rb index a45f2d1..def95cc 100644 --- a/cookbooks/database/libraries/matchers.rb +++ b/cookbooks/database/libraries/matchers.rb @@ -3,7 +3,7 @@ # Cookbook Name:: database # Library:: matchers # -# Copyright 2014, Chef Software, Inc. +# Copyright:: 2014-2016 Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -21,6 +21,8 @@ if defined?(ChefSpec) # database # + ChefSpec.define_matcher :database + def create_database(resource_name) ChefSpec::Matchers::ResourceMatcher.new(:database, :create, resource_name) end @@ -35,6 +37,8 @@ if defined?(ChefSpec) # database user # + ChefSpec.define_matcher :database_user + def create_database_user(resource_name) ChefSpec::Matchers::ResourceMatcher.new(:database_user, :create, resource_name) end @@ -49,6 +53,8 @@ if defined?(ChefSpec) # mysql database # + ChefSpec.define_matcher :mysql_database + def create_mysql_database(resource_name) ChefSpec::Matchers::ResourceMatcher.new(:mysql_database, :create, resource_name) end @@ -63,6 +69,8 @@ if defined?(ChefSpec) # mysql database user # + ChefSpec.define_matcher :mysql_database_user + def create_mysql_database_user(resource_name) ChefSpec::Matchers::ResourceMatcher.new(:mysql_database_user, :create, resource_name) end @@ -77,6 +85,8 @@ if defined?(ChefSpec) # postgresql database # + ChefSpec.define_matcher :postgresql_database + def create_postgresql_database(resource_name) ChefSpec::Matchers::ResourceMatcher.new(:postgresql_database, :create, resource_name) end @@ -91,6 +101,8 @@ if defined?(ChefSpec) # postgresql database schema # + ChefSpec.define_matcher :postgresql_database_schema + def create_postgresql_database_schema(resource_name) ChefSpec::Matchers::ResourceMatcher.new(:postgresql_database_schema, :create, resource_name) end @@ -101,6 +113,8 @@ if defined?(ChefSpec) # postgresql database user # + ChefSpec.define_matcher :postgresql_database_user + def create_postgresql_database_user(resource_name) ChefSpec::Matchers::ResourceMatcher.new(:postgresql_database_user, :create, resource_name) end @@ -119,20 +133,24 @@ if defined?(ChefSpec) # sql server database # + ChefSpec.define_matcher :sql_server_database + def create_sql_server_database(resource_name) ChefSpec::Matchers::ResourceMatcher.new(:sql_server_database, :create, resource_name) end - def drop_database(resource_name) + def drop_sql_server_database(resource_name) ChefSpec::Matchers::ResourceMatcher.new(:sql_server_database, :drop, resource_name) end - def query_database(resource_name) + def query_sql_server_database(resource_name) ChefSpec::Matchers::ResourceMatcher.new(:sql_server_database, :query, resource_name) end # sql server database user # + ChefSpec.define_matcher :sql_server_database_user + def create_sql_server_database_user(resource_name) ChefSpec::Matchers::ResourceMatcher.new(:sql_server_database_user, :create, resource_name) end @@ -148,4 +166,21 @@ if defined?(ChefSpec) def alter_roles_sql_server_database_user(resource_name) ChefSpec::Matchers::ResourceMatcher.new(:sql_server_database_user, :alter_roles, resource_name) end + + # sqlite server database + # + ChefSpec.define_matcher :sqlite_database + + def create_sqlite_database(resource_name) + ChefSpec::Matchers::ResourceMatcher.new(:sqlite_database, :create, resource_name) + end + + def query_sqlite_database(resource_name) + ChefSpec::Matchers::ResourceMatcher.new(:sqlite_database, :query, resource_name) + end + + def drop_sqlite_database(resource_name) + ChefSpec::Matchers::ResourceMatcher.new(:sqlite_database, :drop, resource_name) + end + end diff --git a/cookbooks/database/libraries/provider_database_mysql.rb b/cookbooks/database/libraries/provider_database_mysql.rb index fd1bbe8..acf3809 100644 --- a/cookbooks/database/libraries/provider_database_mysql.rb +++ b/cookbooks/database/libraries/provider_database_mysql.rb @@ -1,7 +1,7 @@ # # Author:: Seth Chisamore () -# Author:: Sean OMeara () -# Copyright:: Copyright (c) 2011 Chef Software, Inc. +# Author:: Sean OMeara () +# Copyright:: 2011-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -21,7 +21,7 @@ class Chef class Provider class Database class Mysql < Chef::Provider::LWRPBase - use_inline_resources if defined?(use_inline_resources) + use_inline_resources def whyrun_supported? true @@ -107,7 +107,9 @@ class Chef socket: new_resource.connection[:socket], username: new_resource.connection[:username], password: new_resource.connection[:password], - port: new_resource.connection[:port] + port: new_resource.connection[:port], + default_file: new_resource.connection[:default_file], + default_group: new_resource.connection[:default_group] ) end @@ -125,7 +127,9 @@ class Chef socket: new_resource.connection[:socket], username: new_resource.connection[:username], password: new_resource.connection[:password], - port: new_resource.connection[:port] + port: new_resource.connection[:port], + default_file: new_resource.connection[:default_file], + default_group: new_resource.connection[:default_group] ) end @@ -144,13 +148,15 @@ class Chef username: new_resource.connection[:username], password: new_resource.connection[:password], port: new_resource.connection[:port], + default_file: new_resource.connection[:default_file], + default_group: new_resource.connection[:default_group], flags: new_resource.connection[:flags], database: new_resource.database_name ) end def close_query_client - @query_client.close + @query_client.close if @query_client rescue Mysql2::Error @query_client = nil end diff --git a/cookbooks/database/libraries/provider_database_mysql_user.rb b/cookbooks/database/libraries/provider_database_mysql_user.rb index fa14265..2cad218 100644 --- a/cookbooks/database/libraries/provider_database_mysql_user.rb +++ b/cookbooks/database/libraries/provider_database_mysql_user.rb @@ -1,7 +1,7 @@ # # Author:: Seth Chisamore () -# Author:: Sean OMeara () -# Copyright:: 2011-2015 Chef Software, Inc. +# Author:: Sean OMeara () +# Copyright:: 2011-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -23,7 +23,7 @@ class Chef class Provider class Database class MysqlUser < Chef::Provider::Database::Mysql - use_inline_resources if defined?(use_inline_resources) + use_inline_resources def whyrun_supported? true @@ -38,6 +38,8 @@ class Chef test_sql_results.each do |r| user_present = true if r['User'] == new_resource.username end + + password_up_to_date = !user_present || test_user_password ensure close_test_client end @@ -47,13 +49,22 @@ class Chef converge_by "Creating user '#{new_resource.username}'@'#{new_resource.host}'" do begin repair_sql = "CREATE USER '#{new_resource.username}'@'#{new_resource.host}'" - repair_sql += " IDENTIFIED BY '#{new_resource.password}'" if new_resource.password + if new_resource.password + repair_sql += ' IDENTIFIED BY ' + repair_sql += if new_resource.password.is_a?(HashedPassword) + " PASSWORD '#{new_resource.password}'" + else + " '#{new_resource.password}'" + end + end repair_client.query(repair_sql) ensure close_repair_client end end end + + update_user_password unless password_up_to_date end action :drop do @@ -89,12 +100,113 @@ class Chef action :grant do # gratuitous function def ishash? - return true if (/(\A\*[0-9A-F]{40}\z)/i).match(new_resource.password) + return true if /(\A\*[0-9A-F]{40}\z)/i =~ new_resource.password end db_name = new_resource.database_name ? "`#{new_resource.database_name}`" : '*' tbl_name = new_resource.table ? new_resource.table : '*' - test_table = new_resource.database_name ? 'mysql.db' : 'mysql.user' + test_table = new_resource.database_name ? 'mysql.db' : 'mysql.user' + + # Test + incorrect_privs = nil + begin + test_sql = "SELECT * from #{test_table}" + test_sql += " WHERE User='#{new_resource.username}'" + test_sql += " AND Host='#{new_resource.host}'" + test_sql += " AND Db='#{new_resource.database_name}'" if new_resource.database_name + test_sql_results = test_client.query test_sql + + incorrect_privs = true if test_sql_results.size == 0 + # These should all be 'Y' + test_sql_results.each do |r| + desired_privs.each do |p| + key = p.to_s.capitalize.tr(' ', '_').gsub('Replication_', 'Repl_').gsub('Create_temporary_tables', 'Create_tmp_table').gsub('Show_databases', 'Show_db') + key = "#{key}_priv" + incorrect_privs = true if r[key] != 'Y' + end + end + + password_up_to_date = incorrect_privs || test_user_password + ensure + close_test_client + end + + # Repair + if incorrect_privs + converge_by "Granting privs for '#{new_resource.username}'@'#{new_resource.host}'" do + begin + repair_sql = "GRANT #{new_resource.privileges.join(',')}" + repair_sql += " ON #{db_name}.#{tbl_name}" + repair_sql += " TO '#{new_resource.username}'@'#{new_resource.host}' IDENTIFIED BY" + repair_sql += if new_resource.password.is_a?(HashedPassword) + " PASSWORD '#{new_resource.password}'" + else + " '#{new_resource.password}'" + end + repair_sql += ' REQUIRE SSL' if new_resource.require_ssl + repair_sql += ' REQUIRE X509' if new_resource.require_x509 + repair_sql += ' WITH GRANT OPTION' if new_resource.grant_option + + Chef::Log.info("#{@new_resource}: granting with sql [#{repair_sql}]") + repair_client.query(repair_sql) + repair_client.query('FLUSH PRIVILEGES') + ensure + close_repair_client + end + end + else + # The grants are correct, but perhaps the password needs updating? + update_user_password unless password_up_to_date + end + end + + action :revoke do + db_name = new_resource.database_name ? "`#{new_resource.database_name}`" : '*' + tbl_name = new_resource.table ? new_resource.table : '*' + test_table = new_resource.database_name ? 'mysql.db' : 'mysql.user' + + privs_to_revoke = [] + begin + test_sql = "SELECT * from #{test_table}" + test_sql += " WHERE User='#{new_resource.username}'" + test_sql += " AND Host='#{new_resource.host}'" + test_sql += " AND Db='#{new_resource.database_name}'" if new_resource.database_name + test_sql_results = test_client.query test_sql + + # These should all be 'N' + test_sql_results.each do |r| + desired_privs.each do |p| + key = p.to_s.capitalize.tr(' ', '_').gsub('Replication_', 'Repl_').gsub('Create_temporary_tables', 'Create_tmp_table').gsub('Show_databases', 'Show_db') + key = "#{key}_priv" + privs_to_revoke << revokify_key(p) if r[key] != 'N' + end + end + ensure + close_test_client + end + + # Repair + unless privs_to_revoke.empty? + converge_by "Granting privs for '#{new_resource.username}'@'#{new_resource.host}'" do + begin + revoke_statement = "REVOKE #{privs_to_revoke.join(',')}" + revoke_statement += " ON #{db_name}.#{tbl_name}" + revoke_statement += " FROM `#{@new_resource.username}`@`#{@new_resource.host}` " + + Chef::Log.info("#{@new_resource}: revoking access with statement [#{revoke_statement}]") + repair_client.query(revoke_statement) + repair_client.query('FLUSH PRIVILEGES') + @new_resource.updated_by_last_action(true) + ensure + close_repair_client + end + end + end + end + + private + + def desired_privs possible_global_privs = [ :select, :insert, @@ -145,76 +257,17 @@ class Chef :trigger ] - if new_resource.privileges == [:all] && new_resource.database_name - desired_privs = possible_db_privs - elsif new_resource.privileges == [:all] - desired_privs = possible_global_privs - else - desired_privs = new_resource.privileges - end - - # Test - incorrect_privs = nil - begin - test_sql = "SELECT * from #{test_table}" - test_sql += " WHERE User='#{new_resource.username}'" - test_sql += " AND Host='#{new_resource.host}'" - test_sql += " AND Db='#{new_resource.database_name}'" if new_resource.database_name - test_sql_results = test_client.query test_sql - - incorrect_privs = true if test_sql_results.size == 0 - # These should all by 'Y' - test_sql_results.each do |r| - desired_privs.each do |p| - key = "#{p.capitalize}" - .gsub(' ', '_') - .gsub('Replication_', 'Repl_') - - key = "#{key}_priv" - - incorrect_privs = true if r[key] != 'Y' - end - end - ensure - close_test_client - end - - # Repair - if incorrect_privs - converge_by "Granting privs for '#{new_resource.username}'@'#{new_resource.host}'" do - begin - repair_sql = "GRANT #{new_resource.privileges.join(',')}" - repair_sql += " ON #{db_name}.#{tbl_name}" - repair_sql += " TO '#{new_resource.username}'@'#{new_resource.host}' IDENTIFIED BY" - repair_sql += " '#{new_resource.password}'" - repair_sql += ' REQUIRE SSL' if new_resource.require_ssl - repair_sql += ' WITH GRANT OPTION' if new_resource.grant_option - - repair_client.query(repair_sql) - repair_client.query('FLUSH PRIVILEGES') - ensure - close_repair_client - end - end - end + # convert :all to the individual db or global privs + desired_privs = if new_resource.privileges == [:all] && new_resource.database_name + possible_db_privs + elsif new_resource.privileges == [:all] + possible_global_privs + else + new_resource.privileges + end + desired_privs end - def action_revoke - db_name = new_resource.database_name ? "`#{new_resource.database_name}`" : '*' - tbl_name = new_resource.table ? new_resource.table : '*' - - revoke_statement = "REVOKE #{@new_resource.privileges.join(', ')}" - revoke_statement += " ON #{db_name}.#{tbl_name}" - revoke_statement += " FROM `#{@new_resource.username}`@`#{@new_resource.host}` " - Chef::Log.info("#{@new_resource}: revoking access with statement [#{revoke_statement}]") - db.query(revoke_statement) - @new_resource.updated_by_last_action(true) - ensure - close - end - - private - def test_client require 'mysql2' @test_client ||= @@ -223,7 +276,9 @@ class Chef socket: new_resource.connection[:socket], username: new_resource.connection[:username], password: new_resource.connection[:password], - port: new_resource.connection[:port] + port: new_resource.connection[:port], + default_file: new_resource.connection[:default_file], + default_group: new_resource.connection[:default_group] ) end @@ -241,7 +296,9 @@ class Chef socket: new_resource.connection[:socket], username: new_resource.connection[:username], password: new_resource.connection[:password], - port: new_resource.connection[:port] + port: new_resource.connection[:port], + default_file: new_resource.connection[:default_file], + default_group: new_resource.connection[:default_group] ) end @@ -250,6 +307,69 @@ class Chef rescue Mysql2::Error @repair_client = nil end + + def revokify_key(key) + return '' if key.nil? + + # Some keys need to be translated as outlined by the table found here: + # https://dev.mysql.com/doc/refman/5.7/en/privileges-provided.html + result = key.to_s.downcase.tr('_', ' ').gsub('repl ', 'replication ').gsub('create tmp table', 'create temporary tables').gsub('show db', 'show databases') + result = result.gsub(/ priv$/, '') + result + end + + def test_user_password + if database_has_password_column(test_client) + test_sql = 'SELECT User,Host,Password FROM mysql.user ' \ + "WHERE User='#{new_resource.username}' AND Host='#{new_resource.host}' " + test_sql += if new_resource.password.is_a? HashedPassword + "AND Password='#{new_resource.password}'" + else + "AND Password=PASSWORD('#{new_resource.password}')" + end + else + test_sql = 'SELECT User,Host,authentication_string FROM mysql.user ' \ + "WHERE User='#{new_resource.username}' AND Host='#{new_resource.host}' " \ + "AND plugin='mysql_native_password' " + test_sql += if new_resource.password.is_a? HashedPassword + "AND authentication_string='#{new_resource.password}'" + else + "AND authentication_string=PASSWORD('#{new_resource.password}')" + end + end + test_client.query(test_sql).size > 0 + end + + def update_user_password + converge_by "Updating password of user '#{new_resource.username}'@'#{new_resource.host}'" do + begin + if database_has_password_column(repair_client) + repair_sql = "SET PASSWORD FOR '#{new_resource.username}'@'#{new_resource.host}' = " + repair_sql += if new_resource.password.is_a? HashedPassword + "'#{new_resource.password}'" + else + " PASSWORD('#{new_resource.password}')" + end + else + # "ALTER USER is now the preferred statement for assigning passwords." + # http://dev.mysql.com/doc/refman/5.7/en/set-password.html + repair_sql = "ALTER USER '#{new_resource.username}'@'#{new_resource.host}' " + repair_sql += if new_resource.password.is_a? HashedPassword + "IDENTIFIED WITH mysql_native_password AS '#{new_resource.password}'" + else + "IDENTIFIED BY '#{new_resource.password}'" + end + end + repair_client.query(repair_sql) + ensure + close_repair_client + end + end + end + + def database_has_password_column(client) + client.query('SHOW COLUMNS FROM mysql.user WHERE Field="Password"').size > 0 + end end end end diff --git a/cookbooks/database/libraries/provider_database_postgresql.rb b/cookbooks/database/libraries/provider_database_postgresql.rb index b49d8f3..c096e0c 100644 --- a/cookbooks/database/libraries/provider_database_postgresql.rb +++ b/cookbooks/database/libraries/provider_database_postgresql.rb @@ -1,7 +1,7 @@ # # Author:: Seth Chisamore () # Author:: Lamont Granquist () -# Copyright:: Copyright (c) 2011 Chef Software, Inc. +# Copyright:: 2011-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -23,7 +23,7 @@ class Chef class Provider class Database class Postgresql < Chef::Provider::LWRPBase - use_inline_resources if defined?(use_inline_resources) + use_inline_resources def whyrun_supported? true @@ -31,7 +31,12 @@ class Chef def load_current_resource Gem.clear_paths - require 'pg' + begin + require 'pg' + rescue LoadError + Chef::Log.fatal('Could not load the required pg gem. Make sure to include the database::postgresql or postgresql::ruby recipes in your runlist') + raise + end @current_resource = Chef::Resource::Database.new(@new_resource.name) @current_resource.database_name(@new_resource.database_name) @current_resource @@ -134,7 +139,11 @@ class Chef end def close - @db.close rescue nil + begin + @db.close + rescue + nil + end @db = nil end end diff --git a/cookbooks/database/libraries/provider_database_postgresql_schema.rb b/cookbooks/database/libraries/provider_database_postgresql_schema.rb index 7c8bd89..77919d2 100644 --- a/cookbooks/database/libraries/provider_database_postgresql_schema.rb +++ b/cookbooks/database/libraries/provider_database_postgresql_schema.rb @@ -1,6 +1,6 @@ # # Author:: Marco Betti () -# Copyright:: Copyright (c) 2013 Chef Software, Inc. +# Copyright:: 2013-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -26,7 +26,12 @@ class Chef def load_current_resource Gem.clear_paths - require 'pg' + begin + require 'pg' + rescue LoadError + Chef::Log.fatal('Could not load the required pg gem. Make sure to include the database::postgresql or postgresql::ruby recipes in your runlist') + raise + end @current_resource = Chef::Resource::PostgresqlDatabaseSchema.new(@new_resource.name) @current_resource.schema_name(@new_resource.schema_name) @current_resource diff --git a/cookbooks/database/libraries/provider_database_postgresql_user.rb b/cookbooks/database/libraries/provider_database_postgresql_user.rb index 8fc47a3..8b9dc3d 100644 --- a/cookbooks/database/libraries/provider_database_postgresql_user.rb +++ b/cookbooks/database/libraries/provider_database_postgresql_user.rb @@ -2,7 +2,7 @@ # Author:: Seth Chisamore () # Author:: Lamont Granquist () # Author:: Marco Betti () -# Copyright:: Copyright (c) 2011 Chef Software, Inc. +# Copyright:: 2011-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -28,7 +28,12 @@ class Chef def load_current_resource Gem.clear_paths - require 'pg' + begin + require 'pg' + rescue LoadError + Chef::Log.fatal('Could not load the required pg gem. Make sure to include the database::postgresql or postgresql::ruby recipes in your runlist') + raise + end @current_resource = Chef::Resource::DatabaseUser.new(@new_resource.name) @current_resource.username(@new_resource.name) @current_resource @@ -39,14 +44,23 @@ class Chef begin options = '' options += " PASSWORD '#{@new_resource.password}'" if @new_resource.password - options += " #{@new_resource.createdb ? 'CREATEDB' : 'NOCREATEDB'}" - options += " #{@new_resource.createrole ? 'CREATEROLE' : 'NOCREATEROLE'}" - options += " #{@new_resource.login ? 'LOGIN' : 'NOLOGIN'}" - options += " #{@new_resource.replication ? 'REPLICATION' : 'NOREPLICATION'}" if version_greater_than?(90_100) - options += " #{@new_resource.superuser ? 'SUPERUSER' : 'NOSUPERUSER'}" + + # Options from Postgresql specific resource + options += " #{@new_resource.createdb ? 'CREATEDB' : 'NOCREATEDB'}" if @new_resource.respond_to?(:createdb) + options += " #{@new_resource.createrole ? 'CREATEROLE' : 'NOCREATEROLE'}" if @new_resource.respond_to?(:createrole) + options += " #{@new_resource.login ? 'LOGIN' : 'NOLOGIN'}" if @new_resource.respond_to?(:login) + options += " #{@new_resource.replication ? 'REPLICATION' : 'NOREPLICATION'}" if @new_resource.respond_to?(:replication) && version_greater_than?(90_100) + options += " #{@new_resource.superuser ? 'SUPERUSER' : 'NOSUPERUSER'}" if @new_resource.respond_to?(:superuser) + + # Options from a non Postgresql specific resource + options += " #{Chef::Resource::PostgresqlDatabaseUser::CREATE_DB_DEFAULT ? 'CREATEDB' : 'NOCREATEDB'}" unless @new_resource.respond_to?(:createdb) + options += " #{Chef::Resource::PostgresqlDatabaseUser::CREATE_ROLE_DEFAULT ? 'CREATEROLE' : 'NOCREATEROLE'}" unless @new_resource.respond_to?(:createrole) + options += " #{Chef::Resource::PostgresqlDatabaseUser::LOGIN_DEFAULT ? 'LOGIN' : 'NOLOGIN'}" unless @new_resource.respond_to?(:login) + options += " #{Chef::Resource::PostgresqlDatabaseUser::REPLICATION_DEFAULT ? 'REPLICATION' : 'NOREPLICATION'}" unless @new_resource.respond_to?(:replication) || !version_greater_than?(90_100) + options += " #{Chef::Resource::PostgresqlDatabaseUser::SUPERUSER_DEFAULT ? 'SUPERUSER' : 'NOSUPERUSER'}" unless @new_resource.respond_to?(:superuser) statement = "CREATE USER \"#{@new_resource.username}\"" - statement += " WITH #{options}" if options.length > 0 + statement += " WITH #{options}" unless options.empty? db('template1').query(statement) @new_resource.updated_by_last_action(true) @@ -85,6 +99,51 @@ class Chef close end + def action_grant_table + grant_statement = "GRANT #{@new_resource.privileges.join(', ')} ON " + grant_statement << if @new_resource.tables.include?(:all) + "ALL TABLES IN SCHEMA \"#{@new_resource.schema_name}\"" + else + "TABLE #{@new_resource.tables.join(', ')}" + end + grant_statement << " TO \"#{@new_resource.username}\"" + Chef::Log.info("#{@new_resource}: granting access with statement [#{grant_statement}]") + db(@new_resource.database_name).query(grant_statement) + @new_resource.updated_by_last_action(true) + ensure + close + end + + def action_grant_sequence + grant_statement = "GRANT #{@new_resource.privileges.join(', ')} ON " + grant_statement << if @new_resource.sequences.include?(:all) + "ALL SEQUENCES IN SCHEMA \"#{@new_resource.schema_name}\"" + else + "SEQUENCE #{@new_resource.sequences.join(', ')}" + end + grant_statement << " TO \"#{@new_resource.username}\"" + Chef::Log.info("#{@new_resource}: granting access with statement [#{grant_statement}]") + db(@new_resource.database_name).query(grant_statement) + @new_resource.updated_by_last_action(true) + ensure + close + end + + def action_grant_function + grant_statement = "GRANT #{@new_resource.privileges.join(', ')} ON " + grant_statement << if @new_resource.functions.include?(:all) + "ALL FUNCTIONS IN SCHEMA \"#{@new_resource.schema_name}\"" + else + "FUNCTION #{@new_resource.functions.join(', ')}" + end + grant_statement << " TO \"#{@new_resource.username}\"" + Chef::Log.info("#{@new_resource}: granting access with statement [#{grant_statement}]") + db(@new_resource.database_name).query(grant_statement) + @new_resource.updated_by_last_action(true) + ensure + close + end + private def exists? diff --git a/cookbooks/database/libraries/provider_database_sql_server.rb b/cookbooks/database/libraries/provider_database_sql_server.rb index 62f2c51..b09f2cb 100644 --- a/cookbooks/database/libraries/provider_database_sql_server.rb +++ b/cookbooks/database/libraries/provider_database_sql_server.rb @@ -1,6 +1,6 @@ # # Author:: Seth Chisamore () -# Copyright:: Copyright (c) 2011 Chef Software, Inc. +# Copyright:: 2011-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -26,7 +26,12 @@ class Chef def load_current_resource Gem.clear_paths - require 'tiny_tds' + begin + require 'tiny_tds' + rescue LoadError + Chef::Log.fatal('Could not load the required tiny_tds gem. Make sure to install this in your wrapper cookbook') + raise + end @current_resource = Chef::Resource::Database.new(@new_resource.name) @current_resource.database_name(@new_resource.database_name) @current_resource @@ -92,17 +97,29 @@ class Chef def db @db ||= begin - ::TinyTds::Client.new( + connection = ::TinyTds::Client.new( host: @new_resource.connection[:host], username: @new_resource.connection[:username], password: @new_resource.connection[:password], - port: @new_resource.connection[:port] || 1433 + port: @new_resource.connection[:port] || 1433, + timeout: @new_resource.connection[:timeout] || 120, + options: @new_resource.connection[:options] || {} ) + if new_resource.connection.include?(:options) + @new_resource.connection[:options].each do |key, value| + connection.execute("SET #{key} #{value}").do + end + end + connection end end def close - @db.close rescue nil + begin + @db.close + rescue + nil + end @db = nil end end diff --git a/cookbooks/database/libraries/provider_database_sql_server_user.rb b/cookbooks/database/libraries/provider_database_sql_server_user.rb index 4580928..4236a32 100644 --- a/cookbooks/database/libraries/provider_database_sql_server_user.rb +++ b/cookbooks/database/libraries/provider_database_sql_server_user.rb @@ -1,6 +1,6 @@ # # Author:: Seth Chisamore () -# Copyright:: Copyright (c) 2011 Chef Software, Inc. +# Copyright:: 2011-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -26,7 +26,12 @@ class Chef def load_current_resource Gem.clear_paths - require 'tiny_tds' + begin + require 'tiny_tds' + rescue LoadError + Chef::Log.fatal('Could not load the required tiny_tds gem. Make sure to install this in your wrapper cookbook') + raise + end @current_resource = Chef::Resource::DatabaseUser.new(@new_resource.name) @current_resource.username(@new_resource.name) @current_resource @@ -106,22 +111,12 @@ class Chef Chef::Log.info("SQL Server Version: #{server_version.inspect}") db.execute('USE [master]').do @new_resource.sql_sys_roles.each do |sql_sys_role, role_action| - case role_action - when 'ADD' - if server_version < '11.00.0000.00' - alter_statement = "EXEC sp_addsrvrolemember '#{@new_resource.username}', '#{sql_sys_role}'" - else - alter_statement = "ALTER SERVER ROLE #{sql_role} #{role_action} MEMBER [#{@new_resource.username}]" - end - Chef::Log.info("#{@new_resource} granting server role membership with statement [#{alter_statement}]") - when 'DROP' - if server_version < '11.00.0000.00' - alter_statement = "EXEC sp_dropsrvrolemember '#{@new_resource.username}', '#{sql_sys_role}'" - else - alter_statement = "ALTER SERVER ROLE #{sql_role} #{role_action} MEMBER [#{@new_resource.username}]" - end - Chef::Log.info("#{@new_resource} revoking server role membership with statement [#{alter_statement}]") - end + alter_statement = if server_version < '11.00.0000.00' + "EXEC sp_#{role_action.downcase}srvrolemember '#{@new_resource.username}', '#{sql_sys_role}'" + else + "ALTER SERVER ROLE #{sql_sys_role} #{role_action} MEMBER [#{@new_resource.username}]" + end + Chef::Log.info("#{@new_resource} granting server role membership with statement [#{alter_statement}]") db.execute(alter_statement).do end @new_resource.updated_by_last_action(true) diff --git a/cookbooks/database/libraries/provider_database_sqlite.rb b/cookbooks/database/libraries/provider_database_sqlite.rb new file mode 100644 index 0000000..738f06c --- /dev/null +++ b/cookbooks/database/libraries/provider_database_sqlite.rb @@ -0,0 +1,96 @@ +# +# Author:: Seth Chisamore () +# Copyright:: Copyright (c) 2011 Chef Software, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require 'chef/provider' + +class Chef + class Provider + class Database + class Sqlite < Chef::Provider + include Chef::Mixin::ShellOut + + def load_current_resource + Gem.clear_paths + begin + require 'sqlite3' + rescue LoadError + Chef::Log.fatal('Could not load the required sqlite3 gem. Make sure to include the database::sqlite recipe on your runlist') + raise + end + @current_resource = Chef::Resource::Database.new(@new_resource.name) + @current_resource.database_name(@new_resource.database_name) + @current_resource + end + + def action_create + unless exists? + ::File.open(@new_resource.database_name, 'w') {} + @new_resource.updated_by_last_action(true) + end + end + + def action_query + if exists? + begin + if @new_resource.sql_query.is_a?(Array) + @new_resource.sql_query.each do |sql| + Chef::Log.debug("#{@new_resource}: Performing queries [#{sql}]") + db.execute(sql) + end + else + Chef::Log.debug("#{@new_resource}: Performing query [#{new_resource.sql_query}]") + db.execute(@new_resource.sql_query) + end + @new_resource.updated_by_last_action(true) + ensure + close + end + end + end + + def action_drop + if exists? + begin + Chef::Log.debug("#{@new_resource}: Dropping database #{new_resource.database_name}") + ::File.unlink(@new_resource.database_name) + @new_resource.updated_by_last_action(true) + ensure + close + end + end + end + + private + + def exists? + ::File.exist?(@new_resource.database_name) + end + + def db + @db ||= begin + ::SQLite3::Database.new(@new_resource.database_name) + end + end + + def close + @db = nil + end + end + end + end +end diff --git a/cookbooks/database/libraries/resource_database.rb b/cookbooks/database/libraries/resource_database.rb index fba2491..99d6cea 100644 --- a/cookbooks/database/libraries/resource_database.rb +++ b/cookbooks/database/libraries/resource_database.rb @@ -1,6 +1,6 @@ # # Author:: Seth Chisamore () -# Copyright:: Copyright (c) 2011 Chef Software, Inc. +# Copyright:: 2011-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/cookbooks/database/libraries/resource_database_user.rb b/cookbooks/database/libraries/resource_database_user.rb index 1247a0b..e1ba359 100644 --- a/cookbooks/database/libraries/resource_database_user.rb +++ b/cookbooks/database/libraries/resource_database_user.rb @@ -1,6 +1,6 @@ # # Author:: Seth Chisamore () -# Copyright:: Copyright (c) 2011 Chef Software, Inc. +# Copyright:: 2011-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -32,6 +32,7 @@ class Chef @privileges = [:all] @grant_option = false @require_ssl = false + @require_x509 = false @allowed_actions.push(:create, :drop, :grant, :revoke) @action = :create @@ -61,6 +62,14 @@ class Chef ) end + def require_x509(arg = nil) + set_or_return( + :require_x509, + arg, + kind_of: [TrueClass, FalseClass] + ) + end + def password(arg = nil) set_or_return( :password, diff --git a/cookbooks/database/libraries/resource_mysql_database.rb b/cookbooks/database/libraries/resource_mysql_database.rb index f82550c..0690257 100644 --- a/cookbooks/database/libraries/resource_mysql_database.rb +++ b/cookbooks/database/libraries/resource_mysql_database.rb @@ -1,7 +1,7 @@ # # Author:: Seth Chisamore () -# Author:: Sean OMeara () -# Copyright:: Copyright (c) 2011 Chef Software, Inc. +# Author:: Sean OMeara () +# Copyright:: 2011-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/cookbooks/database/libraries/resource_mysql_database_user.rb b/cookbooks/database/libraries/resource_mysql_database_user.rb index afe173c..bef62de 100644 --- a/cookbooks/database/libraries/resource_mysql_database_user.rb +++ b/cookbooks/database/libraries/resource_mysql_database_user.rb @@ -1,6 +1,6 @@ # # Author:: Seth Chisamore () -# Copyright:: Copyright (c) 2011 Chef Software, Inc. +# Copyright:: 2011-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -27,6 +27,14 @@ class Chef @resource_name = :mysql_database_user @provider = Chef::Provider::Database::MysqlUser end + + def password(arg = nil) + set_or_return( + :password, + arg, + kind_of: [String, HashedPassword] + ) + end end end end diff --git a/cookbooks/database/libraries/resource_postgresql_database.rb b/cookbooks/database/libraries/resource_postgresql_database.rb index 975176f..dc41c36 100644 --- a/cookbooks/database/libraries/resource_postgresql_database.rb +++ b/cookbooks/database/libraries/resource_postgresql_database.rb @@ -1,7 +1,7 @@ # # Author:: Seth Chisamore () # Author:: Lamont Granquist () -# Copyright:: Copyright (c) 2011 Chef Software, Inc. +# Copyright:: 2011-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/cookbooks/database/libraries/resource_postgresql_database_schema.rb b/cookbooks/database/libraries/resource_postgresql_database_schema.rb index 82c7c5d..0a50fe6 100644 --- a/cookbooks/database/libraries/resource_postgresql_database_schema.rb +++ b/cookbooks/database/libraries/resource_postgresql_database_schema.rb @@ -1,6 +1,6 @@ # # Author:: Marco Betti () -# Copyright:: Copyright (c) 2013 Chef Software, Inc. +# Copyright:: 2013-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/cookbooks/database/libraries/resource_postgresql_database_user.rb b/cookbooks/database/libraries/resource_postgresql_database_user.rb index f73feb0..6e48ffe 100644 --- a/cookbooks/database/libraries/resource_postgresql_database_user.rb +++ b/cookbooks/database/libraries/resource_postgresql_database_user.rb @@ -2,7 +2,7 @@ # Author:: Seth Chisamore () # Author:: Lamont Granquist () # Author:: Marco Betti () -# Copyright:: Copyright (c) 2011 Chef Software, Inc. +# Copyright:: 2011-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -24,17 +24,26 @@ require File.join(File.dirname(__FILE__), 'provider_database_postgresql_user') class Chef class Resource class PostgresqlDatabaseUser < Chef::Resource::DatabaseUser + CREATE_DB_DEFAULT = false unless defined?(CREATE_DB_DEFAULT) + CREATE_ROLE_DEFAULT = false unless defined?(CREATE_ROLE_DEFAULT) + LOGIN_DEFAULT = true unless defined?(LOGIN_DEFAULT) + REPLICATION_DEFAULT = false unless defined?(REPLICATION_DEFAULT) + SUPERUSER_DEFAULT = false unless defined?(SUPERUSER_DEFAULT) + def initialize(name, run_context = nil) super @resource_name = :postgresql_database_user @provider = Chef::Provider::Database::PostgresqlUser - @createdb = false - @createrole = false - @login = true - @replication = false - @superuser = false + @createdb = CREATE_DB_DEFAULT + @createrole = CREATE_ROLE_DEFAULT + @login = LOGIN_DEFAULT + @replication = REPLICATION_DEFAULT + @superuser = SUPERUSER_DEFAULT @schema_name = nil - @allowed_actions.push(:create, :drop, :grant, :grant_schema) + @tables = [:all] + @sequences = [:all] + @functions = [:all] + @allowed_actions.push(:create, :drop, :grant, :grant_schema, :grant_table, :grant_sequence, :grant_function) end def createdb(arg = nil) @@ -61,6 +70,14 @@ class Chef ) end + def password(arg = nil) + set_or_return( + :password, + arg, + kind_of: [String, HashedPassword] + ) + end + def replication(arg = nil) set_or_return( :replication, @@ -84,6 +101,30 @@ class Chef equal_to: [true, false] ) end + + def tables(arg = nil) + set_or_return( + :tables, + arg, + kind_of: Array, default: [:all] + ) + end + + def sequences(arg = nil) + set_or_return( + :sequences, + arg, + kind_of: Array, default: [:all] + ) + end + + def functions(arg = nil) + set_or_return( + :functions, + arg, + kind_of: Array, default: [:all] + ) + end end end end diff --git a/cookbooks/database/libraries/resource_sql_server_database.rb b/cookbooks/database/libraries/resource_sql_server_database.rb index 0822710..515ced7 100644 --- a/cookbooks/database/libraries/resource_sql_server_database.rb +++ b/cookbooks/database/libraries/resource_sql_server_database.rb @@ -1,6 +1,6 @@ # # Author:: Seth Chisamore () -# Copyright:: Copyright (c) 2011 Chef Software, Inc. +# Copyright:: 2011-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/cookbooks/database/libraries/resource_sql_server_database_user.rb b/cookbooks/database/libraries/resource_sql_server_database_user.rb index a63af38..868142b 100644 --- a/cookbooks/database/libraries/resource_sql_server_database_user.rb +++ b/cookbooks/database/libraries/resource_sql_server_database_user.rb @@ -1,6 +1,6 @@ # # Author:: Seth Chisamore () -# Copyright:: Copyright (c) 2011 Chef Software, Inc. +# Copyright:: 2011-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/cookbooks/database/libraries/resource_sqlite_database.rb b/cookbooks/database/libraries/resource_sqlite_database.rb new file mode 100644 index 0000000..b59221a --- /dev/null +++ b/cookbooks/database/libraries/resource_sqlite_database.rb @@ -0,0 +1,40 @@ +# +# Author:: Ronald Doorn () +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require File.join(File.dirname(__FILE__), 'resource_database') +require File.join(File.dirname(__FILE__), 'provider_database_sqlite') + +class Chef + class Resource + class SqliteDatabase < Chef::Resource::Database + def initialize(name, run_context = nil) + super + @resource_name = :sqlite_database + @provider = Chef::Provider::Database::Sqlite + end + + def sql(arg = nil, &block) + arg ||= block + set_or_return( + :sql, + arg, + kind_of: [String, Proc, Array] + ) + end + end + end +end diff --git a/cookbooks/database/metadata.json b/cookbooks/database/metadata.json index 99cc4ae..e0e04d1 100644 --- a/cookbooks/database/metadata.json +++ b/cookbooks/database/metadata.json @@ -1,49 +1 @@ -{ - "name": "database", - "description": "provides LWRPs for common database tasks", - "long_description": "", - "maintainer": "Chef Software, Inc.", - "maintainer_email": "cookbooks@chef.io", - "license": "Apache 2.0", - "platforms": { - "debian": ">= 0.0.0", - "ubuntu": ">= 0.0.0", - "centos": ">= 0.0.0", - "suse": ">= 0.0.0", - "fedora": ">= 0.0.0", - "redhat": ">= 0.0.0", - "scientific": ">= 0.0.0", - "oracle": ">= 0.0.0", - "amazon": ">= 0.0.0" - }, - "dependencies": { - "postgresql": ">= 1.0.0" - }, - "recommendations": { - - }, - "suggestions": { - - }, - "conflicting": { - - }, - "providing": { - - }, - "replacing": { - - }, - "attributes": { - - }, - "groupings": { - - }, - "recipes": { - - }, - "version": "4.0.9", - "source_url": "https://github.com/opscode-cookbooks/database", - "issues_url": "https://github.com/opscode-cookbooks/database/issues" -} +{"name":"database","version":"6.1.1","description":"provides LWRPs for common database tasks","long_description":"# Database Cookbook\n\n[![Build Status](https://travis-ci.org/chef-cookbooks/database.svg?branch=master)](http://travis-ci.org/chef-cookbooks/database) [![Cookbook Version](http://img.shields.io/cookbook/v/database.svg)](https://supermarket.chef.io/cookbooks/database)\n\nThe main highlight of this cookbook is the `database` and `database_user` resources for managing databases and database users in a RDBMS. Providers for MySQL, PostgreSQL and SQL Server are also provided, see usage documentation below.\n\n## Requirements\n\n### Platforms\n\n- Debian / Ubuntu derivatives\n- RHEL derivatives\n- Fedora\n\n### Chef\n\n- Chef 12.1+\n\n### Cookbooks\n\n- postgresql\n\n## Resources/Providers\n\nThese resources aim to expose an abstraction layer for interacting with different RDBMS in a general way. Currently the cookbook ships with providers for MySQL, PostgreSQL and SQL Server. Please see specific usage in the **Example** sections below. The providers use specific Ruby gems installed under Chef's Ruby environment to execute commands and carry out actions. These gems will need to be installed before the providers can operate correctly. Specific notes for each RDBS flavor:\n\n- MySQL: leverages the `mysql2` gem, which can be installed with the `mysql2_chef_gem` resource prior to use (available on the Supermarket). You must depend on the `mysql2_chef_gem` cookbook, then use a `mysql2_chef_gem` resource to install it. The resource allows the user to select MySQL client library versions, as well as optionally select MariaDB libraries.\n\n- PostgreSQL: leverages the `pg` gem which is installed as part of the `postgresql::ruby` recipe. You must declare `include_recipe \"database::postgresql\"` to include this.\n\n- SQL Server: leverages the `tiny_tds` gem which is installed as part of the `sql_server::client` recipe.\n\n- SQLite: leverages the `sqlite3` gem which is installed as part of the `database::sqlite` recipe. You must declare `include_recipe \"database::sqlite\"` to include this.\n\n### database\n\nManage databases in a RDBMS. Use the proper shortcut resource depending on your RDBMS: `mysql_database`, `postgresql_database`, `sql_server_database` or `sqlite_database`.\n\n#### Actions\n\n- `:create`: create a named database\n- `:drop`: drop a named database\n- `:query`: execute an arbitrary query against a named database\n\n#### Attribute Parameters\n\n- database_name: name attribute. Name of the database to interact with\n- connection: hash of connection info. valid keys include `:host`, `:port`, `:username`, and `:password`\n\n - only for MySQL DB*:\n\n - `:flags` (see `Mysql2::Client@@default_query_options[:connect_flags]`)\n - `:default_file`, `:default_group` (see )\n\n - only for PostgreSQL: `:database` (overwrites parameter `database_name`)\n\n - not used for SQLlite\n\n- sql: string of sql or a block that executes to a string of sql, which will be executed against the database. used by `:query` action only\n\n- The database cookbook uses the `mysql2` gem.\n\n> \"The value of host may be either a host name or an IP address. If host is NULL or the string \"127.0.0.1\", a connection to the local host is assumed. For Windows, the client connects using a shared-memory connection, if the server has shared-memory connections enabled. Otherwise, TCP/IP is used. For a host value of \".\" on Windows, the client connects using a named pipe, if the server has named-pipe connections enabled. If named-pipe connections are not enabled, an error occurs.\"\n\nIf you specify a `:socket` key and are using the mysql_service resource to set up the MySQL service, you'll need to specify the path in the form `/var/run/mysql-/mysqld.sock`.\n\n#### Providers\n\n- `Chef::Provider::Database::Mysql`: shortcut resource `mysql_database`\n- `Chef::Provider::Database::Postgresql`: shortcut resource `postgresql_database`\n- `Chef::Provider::Database::SqlServer`: shortcut resource `sql_server_database`\n- `Chef::Provider::Database::Sqlite`: shortcut resource `sqlite_database`\n\n#### Examples\n\n```ruby\n# Create a mysql database\nmysql_database 'wordpress-cust01' do\n connection(\n :host => '127.0.0.1',\n :username => 'root',\n :password => node['wordpress-cust01']['mysql']['initial_root_password']\n )\n action :create\nend\n```\n\n```ruby\n# Create a mysql database on a named mysql instance\nmysql_database 'oracle_rools' do\n connection(\n :host => '127.0.0.1',\n :username => 'root',\n :socket => \"/var/run/mysql-#{instance-name}/mysqld.sock\"\n :password => node['mysql']['server_root_password']\n )\n action :create\nend\n```\n\n```ruby\n# Create a sql server database\nsql_server_database 'mr_softie' do\n connection(\n :host => '127.0.0.1',\n :port => node['sql_server']['port'],\n :username => 'sa',\n :password => node['sql_server']['server_sa_password'],\n :options => { 'ANSI_NULLS' => 'ON', 'QUOTED_IDENTIFIER' => 'OFF' }\n )\n action :create\nend\n```\n\n```ruby\n# create a postgresql database\npostgresql_database 'mr_softie' do\n connection(\n :host => '127.0.0.1',\n :port => 5432,\n :username => 'postgres',\n :password => node['postgresql']['password']['postgres']\n )\n action :create\nend\n```\n\n```ruby\n# create a postgresql database with additional parameters\npostgresql_database 'mr_softie' do\n connection(\n :host => '127.0.0.1',\n :port => 5432,\n :username => 'postgres',\n :password => node['postgresql']['password']['postgres']\n )\n template 'DEFAULT'\n encoding 'DEFAULT'\n tablespace 'DEFAULT'\n connection_limit '-1'\n owner 'postgres'\n action :create\nend\n```\n\n```ruby\n# Externalize conection info in a ruby hash\nmysql_connection_info = {\n :host => '127.0.0.1',\n :username => 'root',\n :password => node['mysql']['server_root_password']\n}\n\nsql_server_connection_info = {\n :host => '127.0.0.1',\n :port => node['sql_server']['port'],\n :username => 'sa',\n :password => node['sql_server']['server_sa_password']\n}\n\npostgresql_connection_info = {\n :host => '127.0.0.1',\n :port => node['postgresql']['config']['port'],\n :username => 'postgres',\n :password => node['postgresql']['password']['postgres']\n}\n\n# Same create commands, connection info as an external hash\nmysql_database 'foo' do\n connection mysql_connection_info\n action :create\nend\n\nsql_server_database 'foo' do\n connection sql_server_connection_info\n action :create\nend\n\npostgresql_database 'foo' do\n connection postgresql_connection_info\n action :create\nend\n\n# Create database, set provider in resource parameter\ndatabase 'bar' do\n connection mysql_connection_info\n provider Chef::Provider::Database::Mysql\n action :create\nend\n\ndatabase 'bar' do\n connection sql_server_connection_info\n provider Chef::Provider::Database::SqlServer\n action :create\nend\n\ndatabase 'bar' do\n connection postgresql_connection_info\n provider Chef::Provider::Database::Postgresql\n action :create\nend\n\n\n\n# Drop a database\nmysql_database 'baz' do\n connection mysql_connection_info\n action :drop\nend\n\n\n\n# Query a database\nmysql_database 'flush the privileges' do\n connection mysql_connection_info\n sql 'flush privileges'\n action :query\nend\n\n\n# Query a database from a sql script on disk\nmysql_database 'run script' do\n connection mysql_connection_info\n sql { ::File.open('/path/to/sql_script.sql').read }\n action :query\nend\n\n\n\n# Vacuum a postgres database\npostgresql_database 'vacuum databases' do\n connection postgresql_connection_info\n database_name 'template1'\n sql 'VACUUM FULL VERBOSE ANALYZE'\n action :query\nend\n```\n\n```ruby\n# Create, Insert, Query a SQLite database\n# Note that inserting anything in to the database will create it automaticly.\nsqlite_database 'mr_softie' do\n database_name '/path/to/database.db3'\n sql \"sql command\"\n action :query\nend\n\n# Delete the database, will remove the file\nsqlite_database 'mr_softie' do\n database_name '/path/to/database.db3'\n action :drop\nend\n```\n\n### database_user\n\nManage users and user privileges in a RDBMS. Use the proper shortcut resource depending on your RDBMS: `mysql_database_user`, `postgresql_database_user`, or `sql_server_database_user`.\n\n#### Actions\n\n- `:create`: create a user\n- `:drop`: drop a user\n- `:grant`: manipulate user privileges on database objects\n\n#### Attribute Parameters\n\n- username: name attribute. Name of the database user\n- password: password for the user account\n- database_name: Name of the database to interact with\n- connection: hash of connection info. valid keys include :host, :port, :username, :password\n- privileges: array of database privileges to grant user. used by the :grant action. default is :all\n- host: host where user connections are allowed from. used by MySQL provider only. default is '127.0.0.1'\n- table: table to grant privileges on. used by :grant action and MySQL provider only. default is '*' (all tables)\n- require_ssl: true or false to force SSL connections to be used for user\n- require_x509: true or false to force SSL with client certificate verification\n\n#### Providers\n\n- `Chef::Provider::Database::MysqlUser`: shortcut resource `mysql_database_user`\n- `Chef::Provider::Database::PostgresqlUser`: shortcut resource `postgresql_database_user`\n- `Chef::Provider::Database::SqlServerUser`: shortcut resource`sql_server_database_user`\n\n#### Examples\n\n```ruby\n# create connection info as an external ruby hash\nmysql_connection_info = {\n :host => '127.0.0.1',\n :username => 'root',\n :password => node['mysql']['server_root_password']\n}\n\npostgresql_connection_info = {\n :host => '127.0.0.1',\n :port => node['postgresql']['config']['port'],\n :username => 'postgres',\n :password => node['postgresql']['password']['postgres']\n}\n\nsql_server_connection_info = {\n :host => '127.0.0.1',\n :port => node['sql_server']['port'],\n :username => 'sa',\n :password => node['sql_server']['server_sa_password']\n}\n\n# Create a mysql user but grant no privileges\nmysql_database_user 'disenfranchised' do\n connection mysql_connection_info\n password 'super_secret'\n action :create\nend\n\n# Do the same but pass the provider to the database resource\ndatabase_user 'disenfranchised' do\n connection mysql_connection_info\n password 'super_secret'\n provider Chef::Provider::Database::MysqlUser\n action :create\nend\n\n# Create a postgresql user but grant no privileges\npostgresql_database_user 'disenfranchised' do\n connection postgresql_connection_info\n password 'super_secret'\n action :create\nend\n\n# The same as above but utilizing hashed password string instead of\n# plain text one\npostgresql_database_user 'disenfranchised' do\n connection postgresql_connection_info\n password hashed_password('md5eacdbf8d9847a76978bd515fae200a2a')\n action :grant\nend\n\n# Do the same but pass the provider to the database resource\ndatabase_user 'disenfranchised' do\n connection postgresql_connection_info\n password 'super_secret'\n provider Chef::Provider::Database::PostgresqlUser\n action :create\nend\n\n# Create a sql server user but grant no privileges\nsql_server_database_user 'disenfranchised' do\n connection sql_server_connection_info\n password 'super_secret'\n action :create\nend\n\n# Drop a mysql user\nmysql_database_user 'foo_user' do\n connection mysql_connection_info\n action :drop\nend\n\n# Bulk drop sql server users\n%w(disenfranchised foo_user).each do |user|\n sql_server_database_user user do\n connection sql_server_connection_info\n action :drop\n end\nend\n\n# Grant SELECT, UPDATE, and INSERT privileges to all tables in foo db from all hosts\nmysql_database_user 'foo_user' do\n connection mysql_connection_info\n password 'super_secret'\n database_name 'foo'\n host '%'\n privileges [:select,:update,:insert]\n action :grant\nend\n\n# The same as above but utilizing hashed password string instead of\n# plain text one\nmysql_database_user 'foo_user' do\n connection mysql_connection_info\n password hashed_password('*664E8D709A6EBADFC68361EBE82CF77F10211E52')\n database_name 'foo'\n host '%'\n privileges [:select,:update,:insert]\n action :grant\nend\n\n# Grant all privileges on all databases/tables from 127.0.0.1\nmysql_database_user 'super_user' do\n connection mysql_connection_info\n password 'super_secret'\n action :grant\nend\n\n# grant all privileges on all tables, sequences and functions in public schema of foo db\npostgresql_database_user 'foo_user' do\n connection postgresql_connection_info\n database_name 'foo'\n schema_name 'public'\n tables [:all]\n sequences [:all]\n functions [:all]\n privileges [:all]\n action [:grant, :grant_schema, :grant_table, :grant_sequence, :grant_function]\nend\n\n# grant select,update,insert privileges to all tables in foo db\nsql_server_database_user 'foo_user' do\n connection sql_server_connection_info\n password 'super_secret'\n database_name 'foo'\n privileges [:select,:update,:insert]\n action :grant\nend\n```\n\n## License & Authors\n\n**Author:** Cookbook Engineering Team ([cookbooks@chef.io](mailto:cookbooks@chef.io))\n\n**Copyright:** 2009-2016, Chef Software, Inc.\n\n```\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```\n","maintainer":"Chef Software, Inc.","maintainer_email":"cookbooks@chef.io","license":"Apache 2.0","platforms":{"amazon":">= 0.0.0","centos":">= 0.0.0","fedora":">= 0.0.0","freebsd":">= 0.0.0","oracle":">= 0.0.0","redhat":">= 0.0.0","scientific":">= 0.0.0","opensuse":">= 0.0.0","opensuseleap":">= 0.0.0","suse":">= 0.0.0","ubuntu":">= 0.0.0"},"dependencies":{"postgresql":">= 1.0.0"},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{}} \ No newline at end of file diff --git a/cookbooks/database/metadata.rb b/cookbooks/database/metadata.rb deleted file mode 100644 index 982087d..0000000 --- a/cookbooks/database/metadata.rb +++ /dev/null @@ -1,21 +0,0 @@ -name 'database' -maintainer 'Chef Software, Inc.' -maintainer_email 'cookbooks@chef.io' -license 'Apache 2.0' -description 'provides LWRPs for common database tasks' -version '4.0.9' - -supports 'debian' -supports 'ubuntu' -supports 'centos' -supports 'suse' -supports 'fedora' -supports 'redhat' -supports 'scientific' -supports 'oracle' -supports 'amazon' - -depends 'postgresql', '>= 1.0.0' - -source_url 'https://github.com/opscode-cookbooks/database' if respond_to?(:source_url) -issues_url 'https://github.com/opscode-cookbooks/database/issues' if respond_to?(:issues_url) diff --git a/cookbooks/database/recipes/postgresql.rb b/cookbooks/database/recipes/postgresql.rb index 0c3774e..69c0a32 100644 --- a/cookbooks/database/recipes/postgresql.rb +++ b/cookbooks/database/recipes/postgresql.rb @@ -1,7 +1,7 @@ # # Author:: Jesse Howarth () # -# Copyright:: Copyright (c) 2012, Chef Software, Inc. () +# Copyright:: 2012-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/cookbooks/database/recipes/sqlite.rb b/cookbooks/database/recipes/sqlite.rb new file mode 100644 index 0000000..b4f348f --- /dev/null +++ b/cookbooks/database/recipes/sqlite.rb @@ -0,0 +1,32 @@ +# +# Author:: Ronald Doorn () +# +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# Install required packages +case node['platform_family'] +when 'rhel', 'fedora' + packages = ['gcc', 'make', 'sqlite-devel', 'sqlite'] +when 'debian', 'ubuntu' + packages = ['gcc', 'make', 'libsqlite3-dev', 'sqlite3'] +end + +package packages + +# Install required gem (will be compiled) +chef_gem 'sqlite3' do + compile_time false +end diff --git a/cookbooks/database/templates/default/app_grants.sql.erb b/cookbooks/database/templates/default/app_grants.sql.erb index 35d8b98..7282172 100644 --- a/cookbooks/database/templates/default/app_grants.sql.erb +++ b/cookbooks/database/templates/default/app_grants.sql.erb @@ -1,4 +1,6 @@ -# Generated by Chef. Local modifications will be overwritten. +# Auto-generated by Chef. +# Local modifications will be overwritten. +# <% @db_info.each do |env,db| -%> # Privileges for databases in <%= env %> GRANT ALL ON <%= db['database'] %>.* TO '<%= db['username'] %>'@'localhost' IDENTIFIED BY '<%= db['password'] %>'; diff --git a/cookbooks/database/templates/default/aws_config.erb b/cookbooks/database/templates/default/aws_config.erb deleted file mode 100644 index e5ae368..0000000 --- a/cookbooks/database/templates/default/aws_config.erb +++ /dev/null @@ -1,3 +0,0 @@ -AWS_ACCESS_KEY_ID=<%= @access_key %> -AWS_SECRET_ACCESS_KEY=<%= @secret_key %> -BUCKET_BASE_NAME=db-backups diff --git a/cookbooks/database/templates/default/ebs-db-backup.sh.erb b/cookbooks/database/templates/default/ebs-db-backup.sh.erb deleted file mode 100644 index 60e1c91..0000000 --- a/cookbooks/database/templates/default/ebs-db-backup.sh.erb +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash -# -# Back up a MySQL database via EBS snapshot - -. /mnt/aws-config/config - -/opt/ec2_mysql/bin/ec2_mysql -a $AWS_ACCESS_KEY_ID -s $AWS_SECRET_ACCESS_KEY -p '<%= @mysql_root_passwd %>' -k 5 master -echo "done" diff --git a/cookbooks/database/templates/default/ebs-db-restore.sh.erb b/cookbooks/database/templates/default/ebs-db-restore.sh.erb deleted file mode 100644 index 47afef6..0000000 --- a/cookbooks/database/templates/default/ebs-db-restore.sh.erb +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash -# -# Restore a MySQL database from EBS - -mkdir -p /mnt/restore - -. /mnt/aws-config/config - -/opt/ec2_mysql/bin/ec2_mysql -a $AWS_ACCESS_KEY_ID -s $AWS_SECRET_ACCESS_KEY -p '<%= @mysql_root_password %>' -v '<%= @ebs_vol_id %>' -m /mnt/restore -d <%= @mysql_device %> -r <%= @mysql_device %> -l debug -n slave -echo "done" diff --git a/cookbooks/database/templates/default/s3cfg.erb b/cookbooks/database/templates/default/s3cfg.erb deleted file mode 100644 index f193656..0000000 --- a/cookbooks/database/templates/default/s3cfg.erb +++ /dev/null @@ -1,27 +0,0 @@ -[default] -access_key = <%= @aws['aws_access_key_id'] %> -acl_public = False -bucket_location = US -debug_syncmatch = False -default_mime_type = binary/octet-stream -delete_removed = False -dry_run = False -encrypt = False -force = False -gpg_command = /usr/bin/gpg -gpg_decrypt = %(gpg_command)s -d --verbose --no-use-agent --batch --yes --passphrase-fd %(passphrase_fd)s -o %(output_file)s %(input_file)s -gpg_encrypt = %(gpg_command)s -c --verbose --no-use-agent --batch --yes --passphrase-fd %(passphrase_fd)s -o %(output_file)s %(input_file)s -gpg_passphrase = -guess_mime_type = False -host_base = s3.amazonaws.com -host_bucket = %(bucket)s.s3.amazonaws.com -human_readable_sizes = False -preserve_attrs = True -proxy_host = -proxy_port = 0 -recv_chunk = 4096 -secret_key = <%= @aws['aws_secret_access_key'] %> -send_chunk = 4096 -simpledb_host = sdb.amazonaws.com -use_https = True -verbosity = WARNING diff --git a/cookbooks/iis/.foodcritic b/cookbooks/iis/.foodcritic index 6c2ff5a..66929c6 100644 --- a/cookbooks/iis/.foodcritic +++ b/cookbooks/iis/.foodcritic @@ -1 +1,2 @@ ~FC059 +~FC023 \ No newline at end of file diff --git a/cookbooks/iis/CHANGELOG.md b/cookbooks/iis/CHANGELOG.md index 4b45c2b..0d31b3c 100644 --- a/cookbooks/iis/CHANGELOG.md +++ b/cookbooks/iis/CHANGELOG.md @@ -2,38 +2,116 @@ This file is used to list changes made in each version of the iis cookbook. +## 6.7.1 (2017-06-09) +- [Fix issue with guard clause missing on check](https://github.com/chef-cookbooks/iis/pull/378) + +## 6.7.0 (2017-06-09) +- [Fix idempotency in `iis_app`, `iis_root`, and `iis_vdir`](https://github.com/chef-cookbooks/iis/pull/375) + +## 6.6.0 (2017-06-01) +- Convert `iis_module` to a custom resource + +## 6.5.3 (2017-05-17) +- Refactor `iis_vdir` name property to `application_name` +- Resolves a bug in iis_vdir also adds more liberty in config + +## 6.5.2 (2017-05-15) +- [Update iis_vdir name to not require a trailing /](https://github.com/chef-cookbooks/iis/pull/363) +- [Fix iis_pool identity_type issue](https://github.com/chef-cookbooks/iis/pull/362) + +## 6.5.1 (2017-05-12) +- [iis_pool is not Idempotent](https://github.com/chef-cookbooks/iis/issues/354) +- Fix whitespace in `iis_pool` name + +## 6.5.0 (2017-05-10) +- Convert `iis_root` to a custom resource +- [uninitialized constant Chef::Resource::IisRoot](https://github.com/chef-cookbooks/iis/issues/333) +- [mime types are not deleted](https://github.com/chef-cookbooks/iis/issues/321) +- [iis_root errors on 'duplicate collection entry of type 'mimeMap'](https://github.com/chef-cookbooks/iis/issues/199) + +## 6.4.1 (2017-05-05) +- [fix bug with start having ! in front](https://github.com/chef-cookbooks/iis/pull/349) + +## 6.4.0 (2017-05-04) +- Convert `iis_section` to a custom resource +- Resolve issue with `iis_pool` + +## 6.3.1 (2017-04-26) + +- [Fix multiple issues with ~FC023](https://github.com/chef-cookbooks/iis/pull/341) + +## 6.3.0 (2017-04-24) + +- Convert `iis_pool` to a custom resource +- Convert `iis_vdir` to a custom resource +- Bug fix for `log` function change to `Chef::Log` + +## 6.2.0 (2017-04-18) + +- Convert `iis_site` to a custom resource + +## 6.1.0 (2017-04-14) + +- Convert `iis_config` to a custom resource + +## 6.0.1 (2017-04-07) + +- Fix undefined method `site_identifier` with iis_app resource. + +## 6.0.0 (2017-04-06) + +- Rewrite of `iis_app` resource to use custom resources. +- Addition of testing for `iis_app` resource. + +## 5.1.0 (2017-03-20) + +- Require at least windows 2.0 cookbook +- Run integration testing in Appveyer +- Switched testing to Inspec from pester/ServerSpec combo +- Removed the empty iis_test cookbook + ## 5.0.8 (2017-03-13) + - [iis-root default_documents broke from last fix](#306) ## 5.0.7 (2017-03-07) + - [iis-root default_documents deleted every chef run](#306) ## 5.0.6 (2017-02-24) + - [iis_version is not evaluated properly on if statement](#308) ## 5.0.5 (2016-11-21) + - [Fixed no_managed_code idempotency](#301) ## 5.0.4 (2016-10-11) + - fixed adding an app pool to a site - This fixes a bug where adding an app pool to a site causes an error. This was using the 'add app' where we are working with a site and the syntax is slightly different according to this [documentation](https://technet.microsoft.com/en-us/library/cc732992%28v=ws.10%29.aspx). ## 5.0.3 (2016-10-10) + - Log event on recycle - This allows you to specify which events you want to log on recycle. This also changes this so that it defaults to the standard nothing, which means you will need to add this attribute if you are depending on it. ## 5.0.2 (2016-10-07) + - [Minor over oversight in IIS::mod_aspnet 5.0.1](#296) - [IIS Pool resource thirty_two_bit false doesn't](#292) ## 5.0.1 (2016-09-21) + - Fix mod_management to include dependencies (#293) ## 5.0.0 (2016-09-06) + - Adding 2k12 version flag to the windows_feature resource (#291) - Testing updates - Avoid deprecation warnings in the specs - Require Chef 12+ ## 4.2.0 (2016-08-09) + - Feature pool recycle virtual memory (#288) ## v4.1.10 (2016-06-29) @@ -115,13 +193,9 @@ This file is used to list changes made in each version of the iis cookbook. - moved to better method for XML checking of previous settings to detect changes (changed all check to use xml searching with appcmd instead of the previous method [none]). - Improved pool resource with many more apppool properties that can be set. - - Fixed bug with default attribute inheritance. - - New recipe to enable ASP.NET 4.5. - - Skeleton serverspec+test-kitchen framework. - - Added Berksfile, Gemfile and .kitchen.yml to assist developers. - Fixed issue [#107] function is_new_or_empty was returning reverse results. - Removed dependency on "chef-client", ">= 3.7.0". diff --git a/cookbooks/iis/MAINTAINERS.md b/cookbooks/iis/MAINTAINERS.md index af785a2..8a8d7fe 100644 --- a/cookbooks/iis/MAINTAINERS.md +++ b/cookbooks/iis/MAINTAINERS.md @@ -1,6 +1,7 @@ # Maintainers + This file lists how this cookbook project is maintained. When making changes to the system, this file tells you who needs to review your patch - you need a review from an existing maintainer for the cookbook to provide a :+1: on your pull request. Additionally, you need to not receive a veto from a Lieutenant or the Project Lead. Check out [How Cookbooks are Maintained](https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/CONTRIBUTING.MD) for details on the process and how to become a maintainer or the project lead. diff --git a/cookbooks/iis/README.md b/cookbooks/iis/README.md index a52b6e4..f7d5362 100644 --- a/cookbooks/iis/README.md +++ b/cookbooks/iis/README.md @@ -1,6 +1,6 @@ # iis Cookbook -[![Build Status](https://travis-ci.org/chef-cookbooks/iis.svg?branch=master)](https://travis-ci.org/chef-cookbooks/iis) [![Cookbook Version](https://img.shields.io/cookbook/v/iis.svg)](https://supermarket.chef.io/cookbooks/iis) +[![Build status](https://ci.appveyor.com/api/projects/status/f4gnv54b97rw1pbg/branch/master?svg=true)](https://ci.appveyor.com/project/ChefWindowsCookbooks/iis/branch/master) [![Cookbook Version](https://img.shields.io/cookbook/v/iis.svg)](https://supermarket.chef.io/cookbooks/iis) Installs and configures Microsoft Internet Information Services (IIS) 7.0 and later @@ -31,17 +31,13 @@ Installs and configures Microsoft Internet Information Services (IIS) 7.0 and la ### Platforms -- Windows Vista -- Windows 7 -- Windows 8, 8.1 - Windows Server 2008 (R1, R2) - Windows Server 2012 (R1, R2) - -Windows 2003R2 is _not_ supported because it lacks Add/Remove Features. +- Windows Server 2016 ### Chef -- Chef 12.1+ +- Chef 12.5+ ### Cookbooks @@ -209,7 +205,6 @@ Runs a config command on your IIS instance. - `:set` - Edit configuration section (appcmd set config) - `:clear` - Clear the section configuration (appcmd clear config) -- `:config` - [ DEPRECATED ] use `:set` instead #### Properties @@ -287,7 +282,7 @@ Creates an application pool in IIS. ##### Root Items -- `pool_name` - name attribute. Specifies the name of the pool to create. +- `name` - name attribute. Specifies the name of the pool to create. - `runtime_version` - specifies what .NET version of the runtime to use. - `pipeline_mode` - specifies what pipeline mode to create the pool with, valid values are :Integrated or :Classic, the default is :Integrated - `no_managed_code` - allow Unmanaged Code in setting up IIS app pools is shutting down. - default is true - optional @@ -301,11 +296,11 @@ Creates an application pool in IIS. ##### Process Model Items -- `max_proc` - specifies the number of worker processes associated with the pool. +- `max_processes` - specifies the number of worker processes associated with the pool. - `load_user_profile` - This property is used only when a service starts in a named user account. - Default is false - optional -- `pool_identity` - the account identity that they app pool will run as, valid values are :SpecificUser, :NetworkService, :LocalService, :LocalSystem, :ApplicationPoolIdentity -- `pool_username` - username for the identity for the application pool -- `pool_password` password for the identity for the application pool is started. Default is true - optional +- `identity_type` - the account identity that they app pool will run as, valid values are :SpecificUser, :NetworkService, :LocalService, :LocalSystem, :ApplicationPoolIdentity +- `username` - username for the identity for the application pool +- `password` password for the identity for the application pool is started. Default is true - optional - `logon_type` - Specifies the logon type for the process identity. (For additional information about [logon types](http://msdn.microsoft.com/en-us/library/aa378184%28VS.85%29.aspx), see the LogonUser Function topic on Microsoft's MSDN Web site.) - Available [:LogonBatch, :LogonService] - default is :LogonBatch - optional - `manual_group_membership` - Specifies whether the IIS_IUSRS group Security Identifier (SID) is added to the worker process token. When false, IIS automatically uses an application pool identity as though it were a member of the built-in IIS_IUSRS group, which has access to necessary file and system resources. When true, an application pool identity must be explicitly added to all resources that a worker process requires at runtime. - default is false - optional - `idle_timeout` - Specifies how long (in minutes) a worker process should run idle if no new requests are received and the worker process is not processing requests. After the allocated time passes, the worker process should request that it be shut down by the WWW service. - default is '00:20:00' - optional @@ -320,12 +315,12 @@ Creates an application pool in IIS. - `disallow_rotation_on_config_change` - The DisallowRotationOnConfigChange property specifies whether or not the World Wide Web Publishing Service (WWW Service) should rotate worker processes in an application pool when the configuration has changed. - Default is false - optional - `disallow_overlapping_rotation` - Specifies whether the WWW Service should start another worker process to replace the existing worker process while that process -- `log_event_on_recycle` - configure IIS to log an event when one or more of the following configured events cause an application pool to recycle (for additional information about [logging events] (https://technet.microsoft.com/en-us/library/cc771318%28v=ws.10%29.aspx). - default is 'Time, Requests, Schedule, Memory, IsapiUnhealthy, OnDemand, ConfigChange, PrivateMemory' - optional +- `log_event_on_recycle` - configure IIS to log an event when one or more of the following configured events cause an application pool to recycle (for additional information about [logging events] (). - default is 'Time, Requests, Schedule, Memory, IsapiUnhealthy, OnDemand, ConfigChange, PrivateMemory' - optional - `recycle_schedule_clear` - specifies a pool to clear all scheduled recycle times, [true,false] Default is false - optional - `recycle_after_time` - specifies a pool to recycle at regular time intervals, d.hh:mm:ss, d optional - `recycle_at_time` - schedule a pool to recycle at a specific time, d.hh:mm:ss, d optional -- `private_mem` - specifies the amount of private memory (in kilobytes) after which you want the pool to recycle -- `virtual_mem` - specifies the amount of virtual memory (in kilobytes) after which you want the pool to recycle +- `private_memory` - specifies the amount of private memory (in kilobytes) after which you want the pool to recycle +- `virtual_memory` - specifies the amount of virtual memory (in kilobytes) after which you want the pool to recycle #### Failure Items @@ -381,11 +376,11 @@ Creates an application in IIS. ```ruby # creates a new app -iis_app "myApp" do - path "/v1_1" - application_pool "myAppPool_v1_1" +iis_app 'myApp' do + path '/v1_1' + application_pool 'myAppPool_v1_1' physical_path "#{node['iis']['docroot']}/testfu/v1_1" - enabled_protocols "http,net.pipe" + enabled_protocols 'http,net.pipe' action :add end ``` @@ -402,7 +397,7 @@ Allows easy management of IIS virtual directories (i.e. vdirs). #### Attribute Parameters -- `application_name`: name attribute. Specifies the name of the application attribute. This is the name of the website or application you are adding it to. +- `application_name`: name attribute. This is the name of the website or site + application you are adding it to. - `path`: The virtual directory path on the site. - `physical_path`: The physical path of the virtual directory on the disk. - `username`: (optional) The username required to logon to the physical_path. If set to "" will clear username and password. @@ -471,7 +466,10 @@ This is valuable to allow the `web.config` of an individual application/website #### Attribute Parameters - `section`: The name of the section to lock. +- `site`: The name of the site you want to lock or unlock a section for. +- `application_path`: The path to the application you want to lock or unlock a section for. - `returns`: The result of the `shell_out` command. +- #### Examples @@ -507,6 +505,25 @@ iis_section 'unlocked web.config globally for Basic auth' do end ``` +```ruby +# Sets the static content section for default web site and root to unlocked +iis_section 'unlock staticContent of default web site' do + section 'system.webServer/staticContent' + site 'Default Web Site' + action :unlock +end +``` + +```ruby +# Sets the static content section for test_app under default website and root to be unlocked +iis_section 'unlock staticContent of default web site' do + section 'system.webServer/staticContent' + site 'Default Web Site' + application_path '/test_app' + action :unlock +end +``` + ### iis_module Manages modules globally or on a per site basis. diff --git a/cookbooks/iis/libraries/constants.rb b/cookbooks/iis/libraries/constants.rb new file mode 100644 index 0000000..8d602f9 --- /dev/null +++ b/cookbooks/iis/libraries/constants.rb @@ -0,0 +1,412 @@ +# +# Cookbook:: iis +# Library:: constants +# +# Copyright:: 2013-2017, Chef Software, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +module Opscode + module IIS + # Contains functions that are used throughout this cookbook + module Constants + def self.default_documents + %w( + Default.htm + Default.asp + index.htm + index.html + iisstart.htm + default.aspx + ) + end + + def self.default_mime_types + %w( + fileExtension='.323',mimeType='text/h323' + fileExtension='.3g2',mimeType='video/3gpp2' + fileExtension='.3gp2',mimeType='video/3gpp2' + fileExtension='.3gp',mimeType='video/3gpp' + fileExtension='.3gpp',mimeType='video/3gpp' + fileExtension='.aaf',mimeType='application/octet-stream' + fileExtension='.aac',mimeType='audio/aac' + fileExtension='.aca',mimeType='application/octet-stream' + fileExtension='.accdb',mimeType='application/msaccess' + fileExtension='.accde',mimeType='application/msaccess' + fileExtension='.accdt',mimeType='application/msaccess' + fileExtension='.acx',mimeType='application/internet-property-stream' + fileExtension='.adt',mimeType='audio/vnd.dlna.adts' + fileExtension='.adts',mimeType='audio/vnd.dlna.adts' + fileExtension='.afm',mimeType='application/octet-stream' + fileExtension='.ai',mimeType='application/postscript' + fileExtension='.aif',mimeType='audio/x-aiff' + fileExtension='.aifc',mimeType='audio/aiff' + fileExtension='.aiff',mimeType='audio/aiff' + fileExtension='.application',mimeType='application/x-ms-application' + fileExtension='.art',mimeType='image/x-jg' + fileExtension='.asd',mimeType='application/octet-stream' + fileExtension='.asf',mimeType='video/x-ms-asf' + fileExtension='.asi',mimeType='application/octet-stream' + fileExtension='.asm',mimeType='text/plain' + fileExtension='.asr',mimeType='video/x-ms-asf' + fileExtension='.asx',mimeType='video/x-ms-asf' + fileExtension='.atom',mimeType='application/atom+xml' + fileExtension='.au',mimeType='audio/basic' + fileExtension='.avi',mimeType='video/avi' + fileExtension='.axs',mimeType='application/olescript' + fileExtension='.bas',mimeType='text/plain' + fileExtension='.bcpio',mimeType='application/x-bcpio' + fileExtension='.bin',mimeType='application/octet-stream' + fileExtension='.bmp',mimeType='image/bmp' + fileExtension='.c',mimeType='text/plain' + fileExtension='.cab',mimeType='application/vnd.ms-cab-compressed' + fileExtension='.calx',mimeType='application/vnd.ms-office.calx' + fileExtension='.cat',mimeType='application/vnd.ms-pki.seccat' + fileExtension='.cdf',mimeType='application/x-cdf' + fileExtension='.chm',mimeType='application/octet-stream' + fileExtension='.class',mimeType='application/x-java-applet' + fileExtension='.clp',mimeType='application/x-msclip' + fileExtension='.cmx',mimeType='image/x-cmx' + fileExtension='.cnf',mimeType='text/plain' + fileExtension='.cod',mimeType='image/cis-cod' + fileExtension='.cpio',mimeType='application/x-cpio' + fileExtension='.cpp',mimeType='text/plain' + fileExtension='.crd',mimeType='application/x-mscardfile' + fileExtension='.crl',mimeType='application/pkix-crl' + fileExtension='.crt',mimeType='application/x-x509-ca-cert' + fileExtension='.csh',mimeType='application/x-csh' + fileExtension='.css',mimeType='text/css' + fileExtension='.csv',mimeType='application/octet-stream' + fileExtension='.cur',mimeType='application/octet-stream' + fileExtension='.dcr',mimeType='application/x-director' + fileExtension='.deploy',mimeType='application/octet-stream' + fileExtension='.der',mimeType='application/x-x509-ca-cert' + fileExtension='.dib',mimeType='image/bmp' + fileExtension='.dir',mimeType='application/x-director' + fileExtension='.disco',mimeType='text/xml' + fileExtension='.dll',mimeType='application/x-msdownload' + fileExtension='.dll.config',mimeType='text/xml' + fileExtension='.dlm',mimeType='text/dlm' + fileExtension='.doc',mimeType='application/msword' + fileExtension='.docm',mimeType='application/vnd.ms-word.document.macroEnabled.12' + fileExtension='.docx',mimeType='application/vnd.openxmlformats-officedocument.wordprocessingml.document' + fileExtension='.dot',mimeType='application/msword' + fileExtension='.dotm',mimeType='application/vnd.ms-word.template.macroEnabled.12' + fileExtension='.dotx',mimeType='application/vnd.openxmlformats-officedocument.wordprocessingml.template' + fileExtension='.dsp',mimeType='application/octet-stream' + fileExtension='.dtd',mimeType='text/xml' + fileExtension='.dvi',mimeType='application/x-dvi' + fileExtension='.dvr-ms',mimeType='video/x-ms-dvr' + fileExtension='.dwf',mimeType='drawing/x-dwf' + fileExtension='.dwp',mimeType='application/octet-stream' + fileExtension='.dxr',mimeType='application/x-director' + fileExtension='.eml',mimeType='message/rfc822' + fileExtension='.emz',mimeType='application/octet-stream' + fileExtension='.eot',mimeType='application/vnd.ms-fontobject' + fileExtension='.eps',mimeType='application/postscript' + fileExtension='.etx',mimeType='text/x-setext' + fileExtension='.evy',mimeType='application/envoy' + fileExtension='.exe',mimeType='application/octet-stream' + fileExtension='.exe.config',mimeType='text/xml' + fileExtension='.fdf',mimeType='application/vnd.fdf' + fileExtension='.fif',mimeType='application/fractals' + fileExtension='.fla',mimeType='application/octet-stream' + fileExtension='.flr',mimeType='x-world/x-vrml' + fileExtension='.flv',mimeType='video/x-flv' + fileExtension='.gif',mimeType='image/gif' + fileExtension='.gtar',mimeType='application/x-gtar' + fileExtension='.gz',mimeType='application/x-gzip' + fileExtension='.h',mimeType='text/plain' + fileExtension='.hdf',mimeType='application/x-hdf' + fileExtension='.hdml',mimeType='text/x-hdml' + fileExtension='.hhc',mimeType='application/x-oleobject' + fileExtension='.hhk',mimeType='application/octet-stream' + fileExtension='.hhp',mimeType='application/octet-stream' + fileExtension='.hlp',mimeType='application/winhlp' + fileExtension='.hqx',mimeType='application/mac-binhex40' + fileExtension='.hta',mimeType='application/hta' + fileExtension='.htc',mimeType='text/x-component' + fileExtension='.htm',mimeType='text/html' + fileExtension='.html',mimeType='text/html' + fileExtension='.htt',mimeType='text/webviewhtml' + fileExtension='.hxt',mimeType='text/html' + fileExtension='.ico',mimeType='image/x-icon' + fileExtension='.ics',mimeType='text/calendar' + fileExtension='.ief',mimeType='image/ief' + fileExtension='.iii',mimeType='application/x-iphone' + fileExtension='.inf',mimeType='application/octet-stream' + fileExtension='.ins',mimeType='application/x-internet-signup' + fileExtension='.isp',mimeType='application/x-internet-signup' + fileExtension='.IVF',mimeType='video/x-ivf' + fileExtension='.jar',mimeType='application/java-archive' + fileExtension='.java',mimeType='application/octet-stream' + fileExtension='.jck',mimeType='application/liquidmotion' + fileExtension='.jcz',mimeType='application/liquidmotion' + fileExtension='.jfif',mimeType='image/pjpeg' + fileExtension='.jpb',mimeType='application/octet-stream' + fileExtension='.jpe',mimeType='image/jpeg' + fileExtension='.jpeg',mimeType='image/jpeg' + fileExtension='.jpg',mimeType='image/jpeg' + fileExtension='.js',mimeType='application/javascript' + fileExtension='.json',mimeType='application/json' + fileExtension='.jsx',mimeType='text/jscript' + fileExtension='.latex',mimeType='application/x-latex' + fileExtension='.lit',mimeType='application/x-ms-reader' + fileExtension='.lpk',mimeType='application/octet-stream' + fileExtension='.lsf',mimeType='video/x-la-asf' + fileExtension='.lsx',mimeType='video/x-la-asf' + fileExtension='.lzh',mimeType='application/octet-stream' + fileExtension='.m13',mimeType='application/x-msmediaview' + fileExtension='.m14',mimeType='application/x-msmediaview' + fileExtension='.m1v',mimeType='video/mpeg' + fileExtension='.m2ts',mimeType='video/vnd.dlna.mpeg-tts' + fileExtension='.m3u',mimeType='audio/x-mpegurl' + fileExtension='.m4a',mimeType='audio/mp4' + fileExtension='.m4v',mimeType='video/mp4' + fileExtension='.man',mimeType='application/x-troff-man' + fileExtension='.manifest',mimeType='application/x-ms-manifest' + fileExtension='.map',mimeType='text/plain' + fileExtension='.mdb',mimeType='application/x-msaccess' + fileExtension='.mdp',mimeType='application/octet-stream' + fileExtension='.me',mimeType='application/x-troff-me' + fileExtension='.mht',mimeType='message/rfc822' + fileExtension='.mhtml',mimeType='message/rfc822' + fileExtension='.mid',mimeType='audio/mid' + fileExtension='.midi',mimeType='audio/mid' + fileExtension='.mix',mimeType='application/octet-stream' + fileExtension='.mmf',mimeType='application/x-smaf' + fileExtension='.mno',mimeType='text/xml' + fileExtension='.mny',mimeType='application/x-msmoney' + fileExtension='.mov',mimeType='video/quicktime' + fileExtension='.movie',mimeType='video/x-sgi-movie' + fileExtension='.mp2',mimeType='video/mpeg' + fileExtension='.mp3',mimeType='audio/mpeg' + fileExtension='.mp4',mimeType='video/mp4' + fileExtension='.mp4v',mimeType='video/mp4' + fileExtension='.mpa',mimeType='video/mpeg' + fileExtension='.mpe',mimeType='video/mpeg' + fileExtension='.mpeg',mimeType='video/mpeg' + fileExtension='.mpg',mimeType='video/mpeg' + fileExtension='.mpp',mimeType='application/vnd.ms-project' + fileExtension='.mpv2',mimeType='video/mpeg' + fileExtension='.ms',mimeType='application/x-troff-ms' + fileExtension='.msi',mimeType='application/octet-stream' + fileExtension='.mso',mimeType='application/octet-stream' + fileExtension='.mvb',mimeType='application/x-msmediaview' + fileExtension='.mvc',mimeType='application/x-miva-compiled' + fileExtension='.nc',mimeType='application/x-netcdf' + fileExtension='.nsc',mimeType='video/x-ms-asf' + fileExtension='.nws',mimeType='message/rfc822' + fileExtension='.ocx',mimeType='application/octet-stream' + fileExtension='.oda',mimeType='application/oda' + fileExtension='.odc',mimeType='text/x-ms-odc' + fileExtension='.ods',mimeType='application/oleobject' + fileExtension='.oga',mimeType='audio/ogg' + fileExtension='.ogg',mimeType='video/ogg' + fileExtension='.ogv',mimeType='video/ogg' + fileExtension='.one',mimeType='application/onenote' + fileExtension='.onea',mimeType='application/onenote' + fileExtension='.onetoc',mimeType='application/onenote' + fileExtension='.onetoc2',mimeType='application/onenote' + fileExtension='.onetmp',mimeType='application/onenote' + fileExtension='.onepkg',mimeType='application/onenote' + fileExtension='.osdx',mimeType='application/opensearchdescription+xml' + fileExtension='.otf',mimeType='font/otf' + fileExtension='.p10',mimeType='application/pkcs10' + fileExtension='.p12',mimeType='application/x-pkcs12' + fileExtension='.p7b',mimeType='application/x-pkcs7-certificates' + fileExtension='.p7c',mimeType='application/pkcs7-mime' + fileExtension='.p7m',mimeType='application/pkcs7-mime' + fileExtension='.p7r',mimeType='application/x-pkcs7-certreqresp' + fileExtension='.p7s',mimeType='application/pkcs7-signature' + fileExtension='.pbm',mimeType='image/x-portable-bitmap' + fileExtension='.pcx',mimeType='application/octet-stream' + fileExtension='.pcz',mimeType='application/octet-stream' + fileExtension='.pdf',mimeType='application/pdf' + fileExtension='.pfb',mimeType='application/octet-stream' + fileExtension='.pfm',mimeType='application/octet-stream' + fileExtension='.pfx',mimeType='application/x-pkcs12' + fileExtension='.pgm',mimeType='image/x-portable-graymap' + fileExtension='.pko',mimeType='application/vnd.ms-pki.pko' + fileExtension='.pma',mimeType='application/x-perfmon' + fileExtension='.pmc',mimeType='application/x-perfmon' + fileExtension='.pml',mimeType='application/x-perfmon' + fileExtension='.pmr',mimeType='application/x-perfmon' + fileExtension='.pmw',mimeType='application/x-perfmon' + fileExtension='.png',mimeType='image/png' + fileExtension='.pnm',mimeType='image/x-portable-anymap' + fileExtension='.pnz',mimeType='image/png' + fileExtension='.pot',mimeType='application/vnd.ms-powerpoint' + fileExtension='.potm',mimeType='application/vnd.ms-powerpoint.template.macroEnabled.12' + fileExtension='.potx',mimeType='application/vnd.openxmlformats-officedocument.presentationml.template' + fileExtension='.ppam',mimeType='application/vnd.ms-powerpoint.addin.macroEnabled.12' + fileExtension='.ppm',mimeType='image/x-portable-pixmap' + fileExtension='.pps',mimeType='application/vnd.ms-powerpoint' + fileExtension='.ppsm',mimeType='application/vnd.ms-powerpoint.slideshow.macroEnabled.12' + fileExtension='.ppsx',mimeType='application/vnd.openxmlformats-officedocument.presentationml.slideshow' + fileExtension='.ppt',mimeType='application/vnd.ms-powerpoint' + fileExtension='.pptm',mimeType='application/vnd.ms-powerpoint.presentation.macroEnabled.12' + fileExtension='.pptx',mimeType='application/vnd.openxmlformats-officedocument.presentationml.presentation' + fileExtension='.prf',mimeType='application/pics-rules' + fileExtension='.prm',mimeType='application/octet-stream' + fileExtension='.prx',mimeType='application/octet-stream' + fileExtension='.ps',mimeType='application/postscript' + fileExtension='.psd',mimeType='application/octet-stream' + fileExtension='.psm',mimeType='application/octet-stream' + fileExtension='.psp',mimeType='application/octet-stream' + fileExtension='.pub',mimeType='application/x-mspublisher' + fileExtension='.qt',mimeType='video/quicktime' + fileExtension='.qtl',mimeType='application/x-quicktimeplayer' + fileExtension='.qxd',mimeType='application/octet-stream' + fileExtension='.ra',mimeType='audio/x-pn-realaudio' + fileExtension='.ram',mimeType='audio/x-pn-realaudio' + fileExtension='.rar',mimeType='application/octet-stream' + fileExtension='.ras',mimeType='image/x-cmu-raster' + fileExtension='.rf',mimeType='image/vnd.rn-realflash' + fileExtension='.rgb',mimeType='image/x-rgb' + fileExtension='.rm',mimeType='application/vnd.rn-realmedia' + fileExtension='.rmi',mimeType='audio/mid' + fileExtension='.roff',mimeType='application/x-troff' + fileExtension='.rpm',mimeType='audio/x-pn-realaudio-plugin' + fileExtension='.rtf',mimeType='application/rtf' + fileExtension='.rtx',mimeType='text/richtext' + fileExtension='.scd',mimeType='application/x-msschedule' + fileExtension='.sct',mimeType='text/scriptlet' + fileExtension='.sea',mimeType='application/octet-stream' + fileExtension='.setpay',mimeType='application/set-payment-initiation' + fileExtension='.setreg',mimeType='application/set-registration-initiation' + fileExtension='.sgml',mimeType='text/sgml' + fileExtension='.sh',mimeType='application/x-sh' + fileExtension='.shar',mimeType='application/x-shar' + fileExtension='.sit',mimeType='application/x-stuffit' + fileExtension='.sldm',mimeType='application/vnd.ms-powerpoint.slide.macroEnabled.12' + fileExtension='.sldx',mimeType='application/vnd.openxmlformats-officedocument.presentationml.slide' + fileExtension='.smd',mimeType='audio/x-smd' + fileExtension='.smi',mimeType='application/octet-stream' + fileExtension='.smx',mimeType='audio/x-smd' + fileExtension='.smz',mimeType='audio/x-smd' + fileExtension='.snd',mimeType='audio/basic' + fileExtension='.snp',mimeType='application/octet-stream' + fileExtension='.spc',mimeType='application/x-pkcs7-certificates' + fileExtension='.spl',mimeType='application/futuresplash' + fileExtension='.spx',mimeType='audio/ogg' + fileExtension='.src',mimeType='application/x-wais-source' + fileExtension='.ssm',mimeType='application/streamingmedia' + fileExtension='.sst',mimeType='application/vnd.ms-pki.certstore' + fileExtension='.stl',mimeType='application/vnd.ms-pki.stl' + fileExtension='.sv4cpio',mimeType='application/x-sv4cpio' + fileExtension='.sv4crc',mimeType='application/x-sv4crc' + fileExtension='.svg',mimeType='image/svg+xml' + fileExtension='.svgz',mimeType='image/svg+xml' + fileExtension='.swf',mimeType='application/x-shockwave-flash' + fileExtension='.t',mimeType='application/x-troff' + fileExtension='.tar',mimeType='application/x-tar' + fileExtension='.tcl',mimeType='application/x-tcl' + fileExtension='.tex',mimeType='application/x-tex' + fileExtension='.texi',mimeType='application/x-texinfo' + fileExtension='.texinfo',mimeType='application/x-texinfo' + fileExtension='.tgz',mimeType='application/x-compressed' + fileExtension='.thmx',mimeType='application/vnd.ms-officetheme' + fileExtension='.thn',mimeType='application/octet-stream' + fileExtension='.tif',mimeType='image/tiff' + fileExtension='.tiff',mimeType='image/tiff' + fileExtension='.toc',mimeType='application/octet-stream' + fileExtension='.tr',mimeType='application/x-troff' + fileExtension='.trm',mimeType='application/x-msterminal' + fileExtension='.ts',mimeType='video/vnd.dlna.mpeg-tts' + fileExtension='.tsv',mimeType='text/tab-separated-values' + fileExtension='.ttf',mimeType='application/octet-stream' + fileExtension='.tts',mimeType='video/vnd.dlna.mpeg-tts' + fileExtension='.txt',mimeType='text/plain' + fileExtension='.u32',mimeType='application/octet-stream' + fileExtension='.uls',mimeType='text/iuls' + fileExtension='.ustar',mimeType='application/x-ustar' + fileExtension='.vbs',mimeType='text/vbscript' + fileExtension='.vcf',mimeType='text/x-vcard' + fileExtension='.vcs',mimeType='text/plain' + fileExtension='.vdx',mimeType='application/vnd.ms-visio.viewer' + fileExtension='.vml',mimeType='text/xml' + fileExtension='.vsd',mimeType='application/vnd.visio' + fileExtension='.vss',mimeType='application/vnd.visio' + fileExtension='.vst',mimeType='application/vnd.visio' + fileExtension='.vsto',mimeType='application/x-ms-vsto' + fileExtension='.vsw',mimeType='application/vnd.visio' + fileExtension='.vsx',mimeType='application/vnd.visio' + fileExtension='.vtx',mimeType='application/vnd.visio' + fileExtension='.wav',mimeType='audio/wav' + fileExtension='.wax',mimeType='audio/x-ms-wax' + fileExtension='.wbmp',mimeType='image/vnd.wap.wbmp' + fileExtension='.wcm',mimeType='application/vnd.ms-works' + fileExtension='.wdb',mimeType='application/vnd.ms-works' + fileExtension='.webm',mimeType='video/webm' + fileExtension='.wks',mimeType='application/vnd.ms-works' + fileExtension='.wm',mimeType='video/x-ms-wm' + fileExtension='.wma',mimeType='audio/x-ms-wma' + fileExtension='.wmd',mimeType='application/x-ms-wmd' + fileExtension='.wmf',mimeType='application/x-msmetafile' + fileExtension='.wml',mimeType='text/vnd.wap.wml' + fileExtension='.wmlc',mimeType='application/vnd.wap.wmlc' + fileExtension='.wmls',mimeType='text/vnd.wap.wmlscript' + fileExtension='.wmlsc',mimeType='application/vnd.wap.wmlscriptc' + fileExtension='.wmp',mimeType='video/x-ms-wmp' + fileExtension='.wmv',mimeType='video/x-ms-wmv' + fileExtension='.wmx',mimeType='video/x-ms-wmx' + fileExtension='.wmz',mimeType='application/x-ms-wmz' + fileExtension='.woff',mimeType='font/x-woff' + fileExtension='.wps',mimeType='application/vnd.ms-works' + fileExtension='.wri',mimeType='application/x-mswrite' + fileExtension='.wrl',mimeType='x-world/x-vrml' + fileExtension='.wrz',mimeType='x-world/x-vrml' + fileExtension='.wsdl',mimeType='text/xml' + fileExtension='.wtv',mimeType='video/x-ms-wtv' + fileExtension='.wvx',mimeType='video/x-ms-wvx' + fileExtension='.x',mimeType='application/directx' + fileExtension='.xaf',mimeType='x-world/x-vrml' + fileExtension='.xaml',mimeType='application/xaml+xml' + fileExtension='.xap',mimeType='application/x-silverlight-app' + fileExtension='.xbap',mimeType='application/x-ms-xbap' + fileExtension='.xbm',mimeType='image/x-xbitmap' + fileExtension='.xdr',mimeType='text/plain' + fileExtension='.xht',mimeType='application/xhtml+xml' + fileExtension='.xhtml',mimeType='application/xhtml+xml' + fileExtension='.xla',mimeType='application/vnd.ms-excel' + fileExtension='.xlam',mimeType='application/vnd.ms-excel.addin.macroEnabled.12' + fileExtension='.xlc',mimeType='application/vnd.ms-excel' + fileExtension='.xlm',mimeType='application/vnd.ms-excel' + fileExtension='.xls',mimeType='application/vnd.ms-excel' + fileExtension='.xlsb',mimeType='application/vnd.ms-excel.sheet.binary.macroEnabled.12' + fileExtension='.xlsm',mimeType='application/vnd.ms-excel.sheet.macroEnabled.12' + fileExtension='.xlsx',mimeType='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' + fileExtension='.xlt',mimeType='application/vnd.ms-excel' + fileExtension='.xltm',mimeType='application/vnd.ms-excel.template.macroEnabled.12' + fileExtension='.xltx',mimeType='application/vnd.openxmlformats-officedocument.spreadsheetml.template' + fileExtension='.xlw',mimeType='application/vnd.ms-excel' + fileExtension='.xml',mimeType='text/xml' + fileExtension='.xof',mimeType='x-world/x-vrml' + fileExtension='.xpm',mimeType='image/x-xpixmap' + fileExtension='.xps',mimeType='application/vnd.ms-xpsdocument' + fileExtension='.xsd',mimeType='text/xml' + fileExtension='.xsf',mimeType='text/xml' + fileExtension='.xsl',mimeType='text/xml' + fileExtension='.xslt',mimeType='text/xml' + fileExtension='.xsn',mimeType='application/octet-stream' + fileExtension='.xtp',mimeType='application/octet-stream' + fileExtension='.xwd',mimeType='image/x-xwindowdump' + fileExtension='.z',mimeType='application/x-compress' + fileExtension='.zip',mimeType='application/x-zip-compressed + ) + end + end + end +end diff --git a/cookbooks/iis/libraries/helper.rb b/cookbooks/iis/libraries/helper.rb index 22a5e89..883ec4d 100644 --- a/cookbooks/iis/libraries/helper.rb +++ b/cookbooks/iis/libraries/helper.rb @@ -2,10 +2,7 @@ # Cookbook:: iis # Library:: helper # -# Author:: Julian C. Dunn -# Author:: Justin Schuhmann -# -# Copyright:: 2013-2016, Chef Software, Inc. +# Copyright:: 2017, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -73,7 +70,25 @@ module Opscode Chef::Util::PathHelper.cleanpath(path) end # Remove any trailing slashes to prevent them from accidentally escaping any quotes. - path.chomp('/').chomp('\\') + path.tr('/', '\\') + end + + def application_cleanname(application_name) + if application_name.count('/') == 0 + "#{application_name}/" + elsif application_name.count('/') > 1 + application_name.chomp('/') + else + application_name + end + end + + def value(document, xpath) + XPath.first(document, xpath).to_s + end + + def bool(value) + value == 'true' end def new_value?(document, xpath, value_to_check) diff --git a/cookbooks/iis/libraries/processors.rb b/cookbooks/iis/libraries/processors.rb index dcb1158..75f1fd0 100644 --- a/cookbooks/iis/libraries/processors.rb +++ b/cookbooks/iis/libraries/processors.rb @@ -1,10 +1,8 @@ # # Cookbook:: iis -# Library:: helper +# Library:: processors # -# Author:: Justin Schuhmann -# -# Copyright:: 2013-2016, Chef Software, Inc. +# Copyright:: 2017, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -23,71 +21,81 @@ module Opscode module IIS # Contains functions that are used throughout this cookbook module Processors - def default_documents(default_document, default_documents_enabled, add = true, remove = true, specifier = '') + def current_default_documents_config(specifier = '') cmd = shell_out! get_default_documents_command specifier return unless cmd.stderr.empty? xml = cmd.stdout doc = REXML::Document.new xml - is_new_default_documents_enabled = new_value?(doc.root, 'CONFIG/system.webServer-defaultDocument/@enabled', default_documents_enabled.to_s) - current_default_documents = REXML::XPath.match(doc.root, 'CONFIG/system.webServer-defaultDocument/files/add/@value').map(&:value) + { + default_documents_enabled: value(doc.root, 'CONFIG/system.webServer-defaultDocument/@enabled'), + default_documents: REXML::XPath.match(doc.root, 'CONFIG/system.webServer-defaultDocument/files/add/@value').map(&:value), + } + end + + def current_mime_maps_config(specifier = '') + # handles mime maps + cmd = shell_out! get_mime_map_command specifier + return unless cmd.stderr.empty? + xml = cmd.stdout + doc = REXML::Document.new xml + + REXML::XPath.match(doc.root, 'CONFIG/system.webServer-staticContent/mimeMap').map { |x| "fileExtension='#{x.attribute 'fileExtension'}',mimeType='#{x.attribute 'mimeType'}'" } + end + + def set_default_documents_enabled(value, specifier = '') cmd = default_documents_command specifier + cmd << " /enabled:#{value}" + shell_out! cmd + end - if is_new_default_documents_enabled - cmd << " /enabled:#{default_documents_enabled}" - end - + def set_default_documents(desired_default_documents, current_default_documents, add = true, remove = true, specifier = '') + cmd = default_documents_command specifier + Chef::Log.warn("new #{desired_default_documents} --- old #{current_default_documents}") if add - (default_document - current_default_documents).each do |document| + (desired_default_documents - current_default_documents).each do |document| cmd << " /+files.[value='#{document}']" end end if remove && !add - (default_document - current_default_documents).each do |document| + (desired_default_documents - current_default_documents).each do |document| cmd << " /-files.[value='#{document}']" end end if remove && add - (current_default_documents - default_document).each do |document| + (current_default_documents - desired_default_documents).each do |document| cmd << " /-files.[value='#{document}']" end end + Chef::Log.warn("before cmd -- #{cmd}") + return unless cmd != default_documents_command(specifier) + Chef::Log.warn("after cmd -- #{cmd}") shell_out! cmd - Chef::Log.info('Default Documents updated') - @was_updated = true end - def mime_maps(new_resource_mime_maps, add = true, remove = true, specifier = '') - # handles mime maps - cmd = shell_out get_mime_map_command specifier - return unless cmd.stderr.empty? - xml = cmd.stdout - doc = REXML::Document.new xml - current_mime_maps = REXML::XPath.match(doc.root, 'CONFIG/system.webServer-staticContent/mimeMap').map { |x| "fileExtension='#{x.attribute 'fileExtension'}',mimeType='#{x.attribute 'mimeType'}'" } + def set_mime_maps(desired_mime_maps, current_mime_maps, add = true, remove = true, specifier = '') cmd = mime_map_command specifier if add - (new_resource_mime_maps - current_mime_maps).each do |mime_map| + (desired_mime_maps - current_mime_maps).each do |mime_map| cmd << " /+\"[#{mime_map}]\"" end end if remove && !add - (new_resource_mime_maps - current_mime_maps).each do |mime_map| + (desired_mime_maps - current_mime_maps).each do |mime_map| cmd << " /-\"[#{mime_map}]\"" end end if remove && add - (current_mime_maps - new_resource_mime_maps).each do |mime_map| + (current_mime_maps - desired_mime_maps).each do |mime_map| cmd << " /-\"[#{mime_map}]\"" end end return unless cmd != mime_map_command(specifier) shell_out! cmd - Chef::Log.info('mime maps updated') - @was_updated = true end private diff --git a/cookbooks/iis/libraries/section_helper.rb b/cookbooks/iis/libraries/section_helper.rb new file mode 100644 index 0000000..8cea5e5 --- /dev/null +++ b/cookbooks/iis/libraries/section_helper.rb @@ -0,0 +1,79 @@ +# +# Cookbook:: iis +# Library:: section-helper +# +# Copyright:: 2017, Chef Software, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +module Opscode + module IIS + # Contains functions that are used throughout this cookbook + module SectionHelper + require 'rexml/document' + include REXML + + def lock(node, section, location = '', returns = [0]) + cmd_list_section node, :lock, section, location, returns + end + + def unlock(node, section, location = '', returns = [0]) + cmd_list_section node, :unlock, section, location, returns + end + + def override_mode(node, action, section, location = '', returns = [0]) + cmd_list_section(node, action, section, location, returns) + end + + def get_current_lock(node, section, location = '') + command_path = 'MACHINE/WEBROOT/APPHOST' + command_path << "/#{location}" if location + cmd = "#{appcmd(node)} list config \"#{command_path}}\"" + cmd << " -section:#{section} -commit:apphost /config:* /xml" + result = shell_out cmd + if result.stderr.empty? + xml = result.stdout + doc = Document.new xml + value(doc.root, 'CONFIG/@overrideMode') + else + Chef::Log.info(result.stderr) + end + + nil + end + + def cmd_section(node, check, section, location, returns) + cmd = "#{appcmd(node)} set config \"MACHINE/WEBROOT/APPHOST/#{location}\"" + cmd << " -section:\"#{section}\" -overrideMode:#{check}" + cmd << ' -commit:apphost' + Chef::Log.debug(cmd) + shell_out!(cmd, returns: returns) + + return unless location + cmd = "#{appcmd(node)} set config \"MACHINE/WEBROOT/APPHOST/#{location}\"" + cmd << " -section:\"#{section}\" -overrideMode:#{check}" + Chef::Log.debug(cmd) + shell_out!(cmd, returns: returns) + end + + def cmd_list_section(node, action, section, location, returns) + current_lock = get_current_lock(node, section, location) + check = action if action == 'Inherit' + check = (action == :lock ? 'Deny' : 'Allow') if action != 'Inherit' + + cmd_section node, check, section, location, returns unless current_lock == check + end + end + end +end diff --git a/cookbooks/iis/metadata.json b/cookbooks/iis/metadata.json index e579ab4..8d06047 100644 --- a/cookbooks/iis/metadata.json +++ b/cookbooks/iis/metadata.json @@ -1 +1 @@ -{"name":"iis","version":"5.0.8","description":"Installs/Configures Microsoft Internet Information Services","long_description":"# iis Cookbook\n\n[![Build Status](https://travis-ci.org/chef-cookbooks/iis.svg?branch=master)](https://travis-ci.org/chef-cookbooks/iis) [![Cookbook Version](https://img.shields.io/cookbook/v/iis.svg)](https://supermarket.chef.io/cookbooks/iis)\n\nInstalls and configures Microsoft Internet Information Services (IIS) 7.0 and later\n\n## Contents\n\n- [Attributes](#attributes)\n- [Resource/Provider](#resourceprovider)\n\n - [iis_root](#iis_root) Allows for easy management of the IIS Root Machine settings\n - [iis_site](#iis_site) Allows for easy management of IIS virtual sites (ie vhosts).\n - [iis_config](#iis_config) Runs a config command on your IIS instance.\n - [iis_pool](#iis_pool) Creates an application pool in IIS.\n - [iis_app](#iis_app) Creates an application in IIS.\n - [iis_vdir](#iis_vdir) Allows easy management of IIS virtual directories (i.e. vdirs).\n - [iis_section](#iis_section) Allows for the locking/unlocking of application web.config sections.\n - [iis_module](#iis_module) Manages modules globally or on a per site basis.\n\n- [Usage](#usage)\n\n - [default](#default) Default recipe\n - [mod_*](#mod_) Recipes for installing individual IIS modules (extensions).\n\n- [Alternatives](#alternative-cookbooks)\n\n- [License and Author](#license-and-author)\n\n## Requirements\n\n### Platforms\n\n- Windows Vista\n- Windows 7\n- Windows 8, 8.1\n- Windows Server 2008 (R1, R2)\n- Windows Server 2012 (R1, R2)\n\nWindows 2003R2 is _not_ supported because it lacks Add/Remove Features.\n\n### Chef\n\n- Chef 12.1+\n\n### Cookbooks\n\n- windows\n\n## Attributes\n\n- `node['iis']['home']` - IIS main home directory. default is `%WINDIR%\\System32\\inetsrv`\n- `node['iis']['conf_dir']` - location where main IIS configs lives. default is `%WINDIR%\\System32\\inetsrv\\config`\n- `node['iis']['pubroot']` - . default is `%SYSTEMDRIVE%\\inetpub`\n- `node['iis']['docroot']` - IIS web site home directory. default is `%SYSTEMDRIVE%\\inetpub\\wwwroot`\n- `node['iis']['log_dir']` - location of IIS logs. default is `%SYSTEMDRIVE%\\inetpub\\logs\\LogFiles`\n- `node['iis']['cache_dir']` - location of cached data. default is `%SYSTEMDRIVE%\\inetpub\\temp`\n\n## Resource/Provider\n\n### iis_root\n\nAllows for easy management of the IIS Root Machine settings\n\n#### Actions\n\n`default` = `:config`\n\n- `:add` - only does addition operations will not delete anything to an Array object\n- `:delete` - only does deletion operations will not add anything to an Array object\n- `:config` - does both addition and deletion make sure your Array objects contain everything you want\n\n#### Properties\n\n- `default_documents_enabled` - Enables or disables default_documents for the root machine, Valid Values: true, false default: `true`\n- `default_documents` - The items you want to set as the default document collection, only used during `:config`. Array of strings, default: `['Default.htm', 'Default.asp', 'index.htm', 'index.html', 'iisstart.htm', 'default.aspx']`\n- `mime_maps` - The items you want to set as the mime-maps or mime-types collection, only used during `:config`. Array of strings, default:\n\n ```ruby\n [\"fileExtension='.323',mimeType='text/h323'\", \"fileExtension='.3g2',mimeType='video/3gpp2'\", \"fileExtension='.3gp2',mimeType='video/3gpp2'\", \"fileExtension='.3gp',mimeType='video/3gpp'\", \"fileExtension='.3gpp',mimeType='video/3gpp'\", \"fileExtension='.aaf',mimeType='application/octet-stream'\", \"fileExtension='.aac',mimeType='audio/aac'\", \"fileExtension='.aca',mimeType='application/octet-stream'\", \"fileExtension='.accdb',mimeType='application/msaccess'\", \"fileExtension='.accde',mimeType='application/msaccess'\", \"fileExtension='.accdt',mimeType='application/msaccess'\", \"fileExtension='.acx',mimeType='application/internet-property-stream'\", \"fileExtension='.adt',mimeType='audio/vnd.dlna.adts'\", \"fileExtension='.adts',mimeType='audio/vnd.dlna.adts'\", \"fileExtension='.afm',mimeType='application/octet-stream'\", \"fileExtension='.ai',mimeType='application/postscript'\", \"fileExtension='.aif',mimeType='audio/x-aiff'\", \"fileExtension='.aifc',mimeType='audio/aiff'\", \"fileExtension='.aiff',mimeType='audio/aiff'\", \"fileExtension='.application',mimeType='application/x-ms-application'\", \"fileExtension='.art',mimeType='image/x-jg'\", \"fileExtension='.asd',mimeType='application/octet-stream'\", \"fileExtension='.asf',mimeType='video/x-ms-asf'\", \"fileExtension='.asi',mimeType='application/octet-stream'\", \"fileExtension='.asm',mimeType='text/plain'\", \"fileExtension='.asr',mimeType='video/x-ms-asf'\", \"fileExtension='.asx',mimeType='video/x-ms-asf'\", \"fileExtension='.atom',mimeType='application/atom+xml'\", \"fileExtension='.au',mimeType='audio/basic'\", \"fileExtension='.avi',mimeType='video/avi'\", \"fileExtension='.axs',mimeType='application/olescript'\", \"fileExtension='.bas',mimeType='text/plain'\", \"fileExtension='.bcpio',mimeType='application/x-bcpio'\", \"fileExtension='.bin',mimeType='application/octet-stream'\", \"fileExtension='.bmp',mimeType='image/bmp'\", \"fileExtension='.c',mimeType='text/plain'\", \"fileExtension='.cab',mimeType='application/vnd.ms-cab-compressed'\", \"fileExtension='.calx',mimeType='application/vnd.ms-office.calx'\", \"fileExtension='.cat',mimeType='application/vnd.ms-pki.seccat'\", \"fileExtension='.cdf',mimeType='application/x-cdf'\", \"fileExtension='.chm',mimeType='application/octet-stream'\", \"fileExtension='.class',mimeType='application/x-java-applet'\", \"fileExtension='.clp',mimeType='application/x-msclip'\", \"fileExtension='.cmx',mimeType='image/x-cmx'\", \"fileExtension='.cnf',mimeType='text/plain'\", \"fileExtension='.cod',mimeType='image/cis-cod'\", \"fileExtension='.cpio',mimeType='application/x-cpio'\", \"fileExtension='.cpp',mimeType='text/plain'\", \"fileExtension='.crd',mimeType='application/x-mscardfile'\", \"fileExtension='.crl',mimeType='application/pkix-crl'\", \"fileExtension='.crt',mimeType='application/x-x509-ca-cert'\", \"fileExtension='.csh',mimeType='application/x-csh'\", \"fileExtension='.css',mimeType='text/css'\", \"fileExtension='.csv',mimeType='application/octet-stream'\", \"fileExtension='.cur',mimeType='application/octet-stream'\", \"fileExtension='.dcr',mimeType='application/x-director'\", \"fileExtension='.deploy',mimeType='application/octet-stream'\", \"fileExtension='.der',mimeType='application/x-x509-ca-cert'\", \"fileExtension='.dib',mimeType='image/bmp'\", \"fileExtension='.dir',mimeType='application/x-director'\", \"fileExtension='.disco',mimeType='text/xml'\", \"fileExtension='.dll',mimeType='application/x-msdownload'\", \"fileExtension='.dll.config',mimeType='text/xml'\", \"fileExtension='.dlm',mimeType='text/dlm'\", \"fileExtension='.doc',mimeType='application/msword'\", \"fileExtension='.docm',mimeType='application/vnd.ms-word.document.macroEnabled.12'\", \"fileExtension='.docx',mimeType='application/vnd.openxmlformats-officedocument.wordprocessingml.document'\", \"fileExtension='.dot',mimeType='application/msword'\", \"fileExtension='.dotm',mimeType='application/vnd.ms-word.template.macroEnabled.12'\", \"fileExtension='.dotx',mimeType='application/vnd.openxmlformats-officedocument.wordprocessingml.template'\", \"fileExtension='.dsp',mimeType='application/octet-stream'\", \"fileExtension='.dtd',mimeType='text/xml'\", \"fileExtension='.dvi',mimeType='application/x-dvi'\", \"fileExtension='.dvr-ms',mimeType='video/x-ms-dvr'\", \"fileExtension='.dwf',mimeType='drawing/x-dwf'\", \"fileExtension='.dwp',mimeType='application/octet-stream'\", \"fileExtension='.dxr',mimeType='application/x-director'\", \"fileExtension='.eml',mimeType='message/rfc822'\", \"fileExtension='.emz',mimeType='application/octet-stream'\", \"fileExtension='.eot',mimeType='application/vnd.ms-fontobject'\", \"fileExtension='.eps',mimeType='application/postscript'\", \"fileExtension='.etx',mimeType='text/x-setext'\", \"fileExtension='.evy',mimeType='application/envoy'\", \"fileExtension='.exe',mimeType='application/octet-stream'\", \"fileExtension='.exe.config',mimeType='text/xml'\", \"fileExtension='.fdf',mimeType='application/vnd.fdf'\", \"fileExtension='.fif',mimeType='application/fractals'\", \"fileExtension='.fla',mimeType='application/octet-stream'\", \"fileExtension='.flr',mimeType='x-world/x-vrml'\", \"fileExtension='.flv',mimeType='video/x-flv'\", \"fileExtension='.gif',mimeType='image/gif'\", \"fileExtension='.gtar',mimeType='application/x-gtar'\", \"fileExtension='.gz',mimeType='application/x-gzip'\", \"fileExtension='.h',mimeType='text/plain'\", \"fileExtension='.hdf',mimeType='application/x-hdf'\", \"fileExtension='.hdml',mimeType='text/x-hdml'\", \"fileExtension='.hhc',mimeType='application/x-oleobject'\", \"fileExtension='.hhk',mimeType='application/octet-stream'\", \"fileExtension='.hhp',mimeType='application/octet-stream'\", \"fileExtension='.hlp',mimeType='application/winhlp'\", \"fileExtension='.hqx',mimeType='application/mac-binhex40'\", \"fileExtension='.hta',mimeType='application/hta'\", \"fileExtension='.htc',mimeType='text/x-component'\", \"fileExtension='.htm',mimeType='text/html'\", \"fileExtension='.html',mimeType='text/html'\", \"fileExtension='.htt',mimeType='text/webviewhtml'\", \"fileExtension='.hxt',mimeType='text/html'\", \"fileExtension='.ico',mimeType='image/x-icon'\", \"fileExtension='.ics',mimeType='text/calendar'\", \"fileExtension='.ief',mimeType='image/ief'\", \"fileExtension='.iii',mimeType='application/x-iphone'\", \"fileExtension='.inf',mimeType='application/octet-stream'\", \"fileExtension='.ins',mimeType='application/x-internet-signup'\", \"fileExtension='.isp',mimeType='application/x-internet-signup'\", \"fileExtension='.IVF',mimeType='video/x-ivf'\", \"fileExtension='.jar',mimeType='application/java-archive'\", \"fileExtension='.java',mimeType='application/octet-stream'\", \"fileExtension='.jck',mimeType='application/liquidmotion'\", \"fileExtension='.jcz',mimeType='application/liquidmotion'\", \"fileExtension='.jfif',mimeType='image/pjpeg'\", \"fileExtension='.jpb',mimeType='application/octet-stream'\", \"fileExtension='.jpe',mimeType='image/jpeg'\", \"fileExtension='.jpeg',mimeType='image/jpeg'\", \"fileExtension='.jpg',mimeType='image/jpeg'\", \"fileExtension='.js',mimeType='application/javascript'\", \"fileExtension='.json',mimeType='application/json'\", \"fileExtension='.jsx',mimeType='text/jscript'\", \"fileExtension='.latex',mimeType='application/x-latex'\", \"fileExtension='.lit',mimeType='application/x-ms-reader'\", \"fileExtension='.lpk',mimeType='application/octet-stream'\", \"fileExtension='.lsf',mimeType='video/x-la-asf'\", \"fileExtension='.lsx',mimeType='video/x-la-asf'\", \"fileExtension='.lzh',mimeType='application/octet-stream'\", \"fileExtension='.m13',mimeType='application/x-msmediaview'\", \"fileExtension='.m14',mimeType='application/x-msmediaview'\", \"fileExtension='.m1v',mimeType='video/mpeg'\", \"fileExtension='.m2ts',mimeType='video/vnd.dlna.mpeg-tts'\", \"fileExtension='.m3u',mimeType='audio/x-mpegurl'\", \"fileExtension='.m4a',mimeType='audio/mp4'\", \"fileExtension='.m4v',mimeType='video/mp4'\", \"fileExtension='.man',mimeType='application/x-troff-man'\", \"fileExtension='.manifest',mimeType='application/x-ms-manifest'\", \"fileExtension='.map',mimeType='text/plain'\", \"fileExtension='.mdb',mimeType='application/x-msaccess'\", \"fileExtension='.mdp',mimeType='application/octet-stream'\", \"fileExtension='.me',mimeType='application/x-troff-me'\", \"fileExtension='.mht',mimeType='message/rfc822'\", \"fileExtension='.mhtml',mimeType='message/rfc822'\", \"fileExtension='.mid',mimeType='audio/mid'\", \"fileExtension='.midi',mimeType='audio/mid'\", \"fileExtension='.mix',mimeType='application/octet-stream'\", \"fileExtension='.mmf',mimeType='application/x-smaf'\", \"fileExtension='.mno',mimeType='text/xml'\", \"fileExtension='.mny',mimeType='application/x-msmoney'\", \"fileExtension='.mov',mimeType='video/quicktime'\", \"fileExtension='.movie',mimeType='video/x-sgi-movie'\", \"fileExtension='.mp2',mimeType='video/mpeg'\", \"fileExtension='.mp3',mimeType='audio/mpeg'\", \"fileExtension='.mp4',mimeType='video/mp4'\", \"fileExtension='.mp4v',mimeType='video/mp4'\", \"fileExtension='.mpa',mimeType='video/mpeg'\", \"fileExtension='.mpe',mimeType='video/mpeg'\", \"fileExtension='.mpeg',mimeType='video/mpeg'\", \"fileExtension='.mpg',mimeType='video/mpeg'\", \"fileExtension='.mpp',mimeType='application/vnd.ms-project'\", \"fileExtension='.mpv2',mimeType='video/mpeg'\", \"fileExtension='.ms',mimeType='application/x-troff-ms'\", \"fileExtension='.msi',mimeType='application/octet-stream'\", \"fileExtension='.mso',mimeType='application/octet-stream'\", \"fileExtension='.mvb',mimeType='application/x-msmediaview'\", \"fileExtension='.mvc',mimeType='application/x-miva-compiled'\", \"fileExtension='.nc',mimeType='application/x-netcdf'\", \"fileExtension='.nsc',mimeType='video/x-ms-asf'\", \"fileExtension='.nws',mimeType='message/rfc822'\", \"fileExtension='.ocx',mimeType='application/octet-stream'\", \"fileExtension='.oda',mimeType='application/oda'\", \"fileExtension='.odc',mimeType='text/x-ms-odc'\", \"fileExtension='.ods',mimeType='application/oleobject'\", \"fileExtension='.oga',mimeType='audio/ogg'\", \"fileExtension='.ogg',mimeType='video/ogg'\", \"fileExtension='.ogv',mimeType='video/ogg'\", \"fileExtension='.one',mimeType='application/onenote'\", \"fileExtension='.onea',mimeType='application/onenote'\", \"fileExtension='.onetoc',mimeType='application/onenote'\", \"fileExtension='.onetoc2',mimeType='application/onenote'\", \"fileExtension='.onetmp',mimeType='application/onenote'\", \"fileExtension='.onepkg',mimeType='application/onenote'\", \"fileExtension='.osdx',mimeType='application/opensearchdescription+xml'\", \"fileExtension='.otf',mimeType='font/otf'\", \"fileExtension='.p10',mimeType='application/pkcs10'\", \"fileExtension='.p12',mimeType='application/x-pkcs12'\", \"fileExtension='.p7b',mimeType='application/x-pkcs7-certificates'\", \"fileExtension='.p7c',mimeType='application/pkcs7-mime'\", \"fileExtension='.p7m',mimeType='application/pkcs7-mime'\", \"fileExtension='.p7r',mimeType='application/x-pkcs7-certreqresp'\", \"fileExtension='.p7s',mimeType='application/pkcs7-signature'\", \"fileExtension='.pbm',mimeType='image/x-portable-bitmap'\", \"fileExtension='.pcx',mimeType='application/octet-stream'\", \"fileExtension='.pcz',mimeType='application/octet-stream'\", \"fileExtension='.pdf',mimeType='application/pdf'\", \"fileExtension='.pfb',mimeType='application/octet-stream'\", \"fileExtension='.pfm',mimeType='application/octet-stream'\", \"fileExtension='.pfx',mimeType='application/x-pkcs12'\", \"fileExtension='.pgm',mimeType='image/x-portable-graymap'\", \"fileExtension='.pko',mimeType='application/vnd.ms-pki.pko'\", \"fileExtension='.pma',mimeType='application/x-perfmon'\", \"fileExtension='.pmc',mimeType='application/x-perfmon'\", \"fileExtension='.pml',mimeType='application/x-perfmon'\", \"fileExtension='.pmr',mimeType='application/x-perfmon'\", \"fileExtension='.pmw',mimeType='application/x-perfmon'\", \"fileExtension='.png',mimeType='image/png'\", \"fileExtension='.pnm',mimeType='image/x-portable-anymap'\", \"fileExtension='.pnz',mimeType='image/png'\", \"fileExtension='.pot',mimeType='application/vnd.ms-powerpoint'\", \"fileExtension='.potm',mimeType='application/vnd.ms-powerpoint.template.macroEnabled.12'\", \"fileExtension='.potx',mimeType='application/vnd.openxmlformats-officedocument.presentationml.template'\", \"fileExtension='.ppam',mimeType='application/vnd.ms-powerpoint.addin.macroEnabled.12'\", \"fileExtension='.ppm',mimeType='image/x-portable-pixmap'\", \"fileExtension='.pps',mimeType='application/vnd.ms-powerpoint'\", \"fileExtension='.ppsm',mimeType='application/vnd.ms-powerpoint.slideshow.macroEnabled.12'\", \"fileExtension='.ppsx',mimeType='application/vnd.openxmlformats-officedocument.presentationml.slideshow'\", \"fileExtension='.ppt',mimeType='application/vnd.ms-powerpoint'\", \"fileExtension='.pptm',mimeType='application/vnd.ms-powerpoint.presentation.macroEnabled.12'\", \"fileExtension='.pptx',mimeType='application/vnd.openxmlformats-officedocument.presentationml.presentation'\", \"fileExtension='.prf',mimeType='application/pics-rules'\", \"fileExtension='.prm',mimeType='application/octet-stream'\", \"fileExtension='.prx',mimeType='application/octet-stream'\", \"fileExtension='.ps',mimeType='application/postscript'\", \"fileExtension='.psd',mimeType='application/octet-stream'\", \"fileExtension='.psm',mimeType='application/octet-stream'\", \"fileExtension='.psp',mimeType='application/octet-stream'\", \"fileExtension='.pub',mimeType='application/x-mspublisher'\", \"fileExtension='.qt',mimeType='video/quicktime'\", \"fileExtension='.qtl',mimeType='application/x-quicktimeplayer'\", \"fileExtension='.qxd',mimeType='application/octet-stream'\", \"fileExtension='.ra',mimeType='audio/x-pn-realaudio'\", \"fileExtension='.ram',mimeType='audio/x-pn-realaudio'\", \"fileExtension='.rar',mimeType='application/octet-stream'\", \"fileExtension='.ras',mimeType='image/x-cmu-raster'\", \"fileExtension='.rf',mimeType='image/vnd.rn-realflash'\", \"fileExtension='.rgb',mimeType='image/x-rgb'\", \"fileExtension='.rm',mimeType='application/vnd.rn-realmedia'\", \"fileExtension='.rmi',mimeType='audio/mid'\", \"fileExtension='.roff',mimeType='application/x-troff'\", \"fileExtension='.rpm',mimeType='audio/x-pn-realaudio-plugin'\", \"fileExtension='.rtf',mimeType='application/rtf'\", \"fileExtension='.rtx',mimeType='text/richtext'\", \"fileExtension='.scd',mimeType='application/x-msschedule'\", \"fileExtension='.sct',mimeType='text/scriptlet'\", \"fileExtension='.sea',mimeType='application/octet-stream'\", \"fileExtension='.setpay',mimeType='application/set-payment-initiation'\", \"fileExtension='.setreg',mimeType='application/set-registration-initiation'\", \"fileExtension='.sgml',mimeType='text/sgml'\", \"fileExtension='.sh',mimeType='application/x-sh'\", \"fileExtension='.shar',mimeType='application/x-shar'\", \"fileExtension='.sit',mimeType='application/x-stuffit'\", \"fileExtension='.sldm',mimeType='application/vnd.ms-powerpoint.slide.macroEnabled.12'\", \"fileExtension='.sldx',mimeType='application/vnd.openxmlformats-officedocument.presentationml.slide'\", \"fileExtension='.smd',mimeType='audio/x-smd'\", \"fileExtension='.smi',mimeType='application/octet-stream'\", \"fileExtension='.smx',mimeType='audio/x-smd'\", \"fileExtension='.smz',mimeType='audio/x-smd'\", \"fileExtension='.snd',mimeType='audio/basic'\", \"fileExtension='.snp',mimeType='application/octet-stream'\", \"fileExtension='.spc',mimeType='application/x-pkcs7-certificates'\", \"fileExtension='.spl',mimeType='application/futuresplash'\", \"fileExtension='.spx',mimeType='audio/ogg'\", \"fileExtension='.src',mimeType='application/x-wais-source'\", \"fileExtension='.ssm',mimeType='application/streamingmedia'\", \"fileExtension='.sst',mimeType='application/vnd.ms-pki.certstore'\", \"fileExtension='.stl',mimeType='application/vnd.ms-pki.stl'\", \"fileExtension='.sv4cpio',mimeType='application/x-sv4cpio'\", \"fileExtension='.sv4crc',mimeType='application/x-sv4crc'\", \"fileExtension='.svg',mimeType='image/svg+xml'\", \"fileExtension='.svgz',mimeType='image/svg+xml'\", \"fileExtension='.swf',mimeType='application/x-shockwave-flash'\", \"fileExtension='.t',mimeType='application/x-troff'\", \"fileExtension='.tar',mimeType='application/x-tar'\", \"fileExtension='.tcl',mimeType='application/x-tcl'\", \"fileExtension='.tex',mimeType='application/x-tex'\", \"fileExtension='.texi',mimeType='application/x-texinfo'\", \"fileExtension='.texinfo',mimeType='application/x-texinfo'\", \"fileExtension='.tgz',mimeType='application/x-compressed'\", \"fileExtension='.thmx',mimeType='application/vnd.ms-officetheme'\", \"fileExtension='.thn',mimeType='application/octet-stream'\", \"fileExtension='.tif',mimeType='image/tiff'\", \"fileExtension='.tiff',mimeType='image/tiff'\", \"fileExtension='.toc',mimeType='application/octet-stream'\", \"fileExtension='.tr',mimeType='application/x-troff'\", \"fileExtension='.trm',mimeType='application/x-msterminal'\", \"fileExtension='.ts',mimeType='video/vnd.dlna.mpeg-tts'\", \"fileExtension='.tsv',mimeType='text/tab-separated-values'\", \"fileExtension='.ttf',mimeType='application/octet-stream'\", \"fileExtension='.tts',mimeType='video/vnd.dlna.mpeg-tts'\", \"fileExtension='.txt',mimeType='text/plain'\", \"fileExtension='.u32',mimeType='application/octet-stream'\", \"fileExtension='.uls',mimeType='text/iuls'\", \"fileExtension='.ustar',mimeType='application/x-ustar'\", \"fileExtension='.vbs',mimeType='text/vbscript'\", \"fileExtension='.vcf',mimeType='text/x-vcard'\", \"fileExtension='.vcs',mimeType='text/plain'\", \"fileExtension='.vdx',mimeType='application/vnd.ms-visio.viewer'\", \"fileExtension='.vml',mimeType='text/xml'\", \"fileExtension='.vsd',mimeType='application/vnd.visio'\", \"fileExtension='.vss',mimeType='application/vnd.visio'\", \"fileExtension='.vst',mimeType='application/vnd.visio'\", \"fileExtension='.vsto',mimeType='application/x-ms-vsto'\", \"fileExtension='.vsw',mimeType='application/vnd.visio'\", \"fileExtension='.vsx',mimeType='application/vnd.visio'\", \"fileExtension='.vtx',mimeType='application/vnd.visio'\", \"fileExtension='.wav',mimeType='audio/wav'\", \"fileExtension='.wax',mimeType='audio/x-ms-wax'\", \"fileExtension='.wbmp',mimeType='image/vnd.wap.wbmp'\", \"fileExtension='.wcm',mimeType='application/vnd.ms-works'\", \"fileExtension='.wdb',mimeType='application/vnd.ms-works'\", \"fileExtension='.webm',mimeType='video/webm'\", \"fileExtension='.wks',mimeType='application/vnd.ms-works'\", \"fileExtension='.wm',mimeType='video/x-ms-wm'\", \"fileExtension='.wma',mimeType='audio/x-ms-wma'\", \"fileExtension='.wmd',mimeType='application/x-ms-wmd'\", \"fileExtension='.wmf',mimeType='application/x-msmetafile'\", \"fileExtension='.wml',mimeType='text/vnd.wap.wml'\", \"fileExtension='.wmlc',mimeType='application/vnd.wap.wmlc'\", \"fileExtension='.wmls',mimeType='text/vnd.wap.wmlscript'\", \"fileExtension='.wmlsc',mimeType='application/vnd.wap.wmlscriptc'\", \"fileExtension='.wmp',mimeType='video/x-ms-wmp'\", \"fileExtension='.wmv',mimeType='video/x-ms-wmv'\", \"fileExtension='.wmx',mimeType='video/x-ms-wmx'\", \"fileExtension='.wmz',mimeType='application/x-ms-wmz'\", \"fileExtension='.woff',mimeType='font/x-woff'\", \"fileExtension='.wps',mimeType='application/vnd.ms-works'\", \"fileExtension='.wri',mimeType='application/x-mswrite'\", \"fileExtension='.wrl',mimeType='x-world/x-vrml'\", \"fileExtension='.wrz',mimeType='x-world/x-vrml'\", \"fileExtension='.wsdl',mimeType='text/xml'\", \"fileExtension='.wtv',mimeType='video/x-ms-wtv'\", \"fileExtension='.wvx',mimeType='video/x-ms-wvx'\", \"fileExtension='.x',mimeType='application/directx'\", \"fileExtension='.xaf',mimeType='x-world/x-vrml'\", \"fileExtension='.xaml',mimeType='application/xaml+xml'\", \"fileExtension='.xap',mimeType='application/x-silverlight-app'\", \"fileExtension='.xbap',mimeType='application/x-ms-xbap'\", \"fileExtension='.xbm',mimeType='image/x-xbitmap'\", \"fileExtension='.xdr',mimeType='text/plain'\", \"fileExtension='.xht',mimeType='application/xhtml+xml'\", \"fileExtension='.xhtml',mimeType='application/xhtml+xml'\", \"fileExtension='.xla',mimeType='application/vnd.ms-excel'\", \"fileExtension='.xlam',mimeType='application/vnd.ms-excel.addin.macroEnabled.12'\", \"fileExtension='.xlc',mimeType='application/vnd.ms-excel'\", \"fileExtension='.xlm',mimeType='application/vnd.ms-excel'\", \"fileExtension='.xls',mimeType='application/vnd.ms-excel'\", \"fileExtension='.xlsb',mimeType='application/vnd.ms-excel.sheet.binary.macroEnabled.12'\", \"fileExtension='.xlsm',mimeType='application/vnd.ms-excel.sheet.macroEnabled.12'\", \"fileExtension='.xlsx',mimeType='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'\", \"fileExtension='.xlt',mimeType='application/vnd.ms-excel'\", \"fileExtension='.xltm',mimeType='application/vnd.ms-excel.template.macroEnabled.12'\", \"fileExtension='.xltx',mimeType='application/vnd.openxmlformats-officedocument.spreadsheetml.template'\", \"fileExtension='.xlw',mimeType='application/vnd.ms-excel'\", \"fileExtension='.xml',mimeType='text/xml'\", \"fileExtension='.xof',mimeType='x-world/x-vrml'\", \"fileExtension='.xpm',mimeType='image/x-xpixmap'\", \"fileExtension='.xps',mimeType='application/vnd.ms-xpsdocument'\", \"fileExtension='.xsd',mimeType='text/xml'\", \"fileExtension='.xsf',mimeType='text/xml'\", \"fileExtension='.xsl',mimeType='text/xml'\", \"fileExtension='.xslt',mimeType='text/xml'\", \"fileExtension='.xsn',mimeType='application/octet-stream'\", \"fileExtension='.xtp',mimeType='application/octet-stream'\", \"fileExtension='.xwd',mimeType='image/x-xwindowdump'\", \"fileExtension='.z',mimeType='application/x-compress'\", \"fileExtension='.zip',mimeType='application/x-zip-compressed'\"]\n ```\n\n- `add_default_documents` - The items you want to add to the default document collection, only used during `:add`. Array of strings, default: `[]`\n\n- `add_mime_maps` - The items you want to add to the mime-map/mime-type collection, only used during `:add`. Array of strings, default: `[]`\n\n- `delete_default_documents` - The items you want to delete from the default document collection, only used during `:delete`. Array of strings, default: `[]`\n\n- `delete_mime_maps` - The items you want to delete from the mime-map/mime-type collection, only used during `:delete`. Array of strings, default: `[]`\n\n#### Examples\n\n```ruby\n# Add foo.html to default documents, and add '.dmg' as mime type extension at root level\niis_root 'add stuff' do\n add_default_documents ['foo.html']\n add_mime_maps [\"fileExtension='.dmg',mimeType='application/octet-stream'\"]\n action :add\nend\n```\n\n```ruby\n# Remove index.html from default document and .323 as a mime type at root level\niis_root 'delete stuff' do\n delete_default_documents ['index.html']\n delete_mime_maps [\"fileExtension='.323',mimeType='text/h323'\"]\n action :delete\nend\n```\n\n### iis_site\n\nAllows for easy management of IIS virtual sites (ie vhosts).\n\n#### Actions\n\n- `:add` - add a new virtual site\n- `:config` - apply configuration to an existing virtual site\n- `:delete` - delete an existing virtual site\n- `:start` - start a virtual site\n- `:stop` - stop a virtual site\n- `:restart` - restart a virtual site\n\n#### Properties\n\n- `site_name` - name attribute.\n- `site_id` - if not given IIS generates a unique ID for the site\n- `path` - IIS will create a root application and a root virtual directory mapped to this specified local path\n- `protocol` - http protocol type the site should respond to. valid values are :http, :https. default is :http\n- `port` - port site will listen on. default is 80\n- `host_header` - host header (also known as domains or host names) the site should map to. default is all host headers\n- `options` - additional options to configure the site\n- `bindings` - Advanced options to configure the information required for requests to communicate with a Web site. See for parameter format. When binding is used, port protocol and host_header should not be used.\n- `application_pool` - set the application pool of the site\n- `options` - support for additional options -logDir, -limits, -ftpServer, etc...\n- `log_directory` - specifies the logging directory, where the log file and logging-related support files are stored.\n- `log_period` - specifies how often iis creates a new log file\n- `log_truncsize` - specifies the maximum size of the log file (in bytes) after which to create a new log file.\n\n#### Examples\n\n```ruby\n# stop and delete the default site\niis_site 'Default Web Site' do\n action [:stop, :delete]\nend\n```\n\n```ruby\n# create and start a new site that maps to\n# the physical location C:\\inetpub\\wwwroot\\testfu\n# first the physical location must exist\ndirectory \"#{node['iis']['docroot']}/testfu\" do\n action :create\nend\n\n# now create and start the site (note this will use the default application pool which must exist)\niis_site 'Testfu Site' do\n protocol :http\n port 80\n path \"#{node['iis']['docroot']}/testfu\"\n action [:add,:start]\nend\n```\n\n```ruby\n# do the same but map to testfu.chef.io domain\n# first the physical location must exist\ndirectory \"#{node['iis']['docroot']}/testfu\" do\n action :create\nend\n\n# now create and start the site (note this will use the default application pool which must exist)\niis_site 'Testfu Site' do\n protocol :http\n port 80\n path \"#{node['iis']['docroot']}/testfu\"\n host_header \"testfu.chef.io\"\n action [:add,:start]\nend\n```\n\n```ruby\n# create and start a new site that maps to\n# the physical C:\\inetpub\\wwwroot\\testfu\n# first the physical location must exist\ndirectory \"#{node['iis']['docroot']}/testfu\" do\n action :create\nend\n\n# also adds bindings to http and https\n# binding http to the ip address 10.12.0.136,\n# the port 80, and the host header www.domain.com\n# also binding https to any ip address,\n# the port 443, and the host header www.domain.com\n# now create and start the site (note this will use the default application pool which must exist)\niis_site 'FooBar Site' do\n bindings \"http/10.12.0.136:80:www.domain.com,https/*:443:www.domain.com\n path \"#{node['iis']['docroot']}/testfu\"\n action [:add,:start]\nend\n```\n\n### iis_config\n\nRuns a config command on your IIS instance.\n\n#### Actions\n\n- `:set` - Edit configuration section (appcmd set config)\n- `:clear` - Clear the section configuration (appcmd clear config)\n- `:config` - [ DEPRECATED ] use `:set` instead\n\n#### Properties\n\n- `cfg_cmd` - name attribute. What ever command you would pass in after \"appcmd.exe set config\"\n\n#### Example\n\n```ruby\n# Sets up logging\niis_config \"/section:system.applicationHost/sites /siteDefaults.logfile.directory:\\\"D:\\\\logs\\\"\" do\n action :set\nend\n```\n\n```ruby\n# Increase file upload size for 'MySite'\niis_config \"\\\"MySite\\\" /section:requestfiltering /requestlimits.maxallowedcontentlength:50000000\" do\n action :set\nend\n```\n\n```ruby\n# Set IUSR username and password authentication\niis_config \"\\\"MyWebsite/aSite\\\" -section:system.webServer/security/authentication/anonymousAuthentication /enabled:\\\"True\\\" /userName:\\\"IUSR_foobar\\\" /password:\\\"p@assword\\\" /commit:apphost\" do\n action :set\nend\n```\n\n```ruby\n# Authenticate with application pool\niis_config \"\\\"MyWebsite/aSite\\\" -section:system.webServer/security/authentication/anonymousAuthentication /enabled:\\\"True\\\" /userName:\\\"\\\" /commit:apphost\" do\n action :set\nend\n```\n\n```ruby\n# Loads an array of commands from the node\ncfg_cmds = node['iis']['cfg_cmd']\ncfg_cmds.each do |cmd|\n iis_config \"#{cmd}\" do\n action :set\n end\nend\n```\n\n```ruby\n# Add static machine key at site level\niis_config \"MySite /commit:site /section:machineKey /validation:AES /validationKey:AAAAAA /decryptionKey:ZZZZZ\" do\n action :set\nend\n```\n\n```ruby\n# Remove machine key\niis_config \"MySite /commit:site /section:machineKey\" do\n action :clear\nend\n```\n\n### iis_pool\n\nCreates an application pool in IIS.\n\n#### Actions\n\n- `:add` - add a new application pool\n- `:config` - apply configuration to an existing application pool\n- `:delete` - delete an existing application pool\n- `:start` - start a application pool\n- `:stop` - stop a application pool\n- `:restart` - restart a application pool\n- `:recycle` - recycle an application pool\n\n#### Properties\n\n##### Root Items\n\n- `pool_name` - name attribute. Specifies the name of the pool to create.\n- `runtime_version` - specifies what .NET version of the runtime to use.\n- `pipeline_mode` - specifies what pipeline mode to create the pool with, valid values are :Integrated or :Classic, the default is :Integrated\n- `no_managed_code` - allow Unmanaged Code in setting up IIS app pools is shutting down. - default is true - optional\n\n##### Add Items\n\n- `start_mode` - Specifies the startup type for the application pool - default :OnDemand (:OnDemand, :AlwaysRunning) - optional\n- `auto_start` - When true, indicates to the World Wide Web Publishing Service (W3SVC) that the application pool should be automatically started when it is created or when IIS is started. - boolean: default true - optional\n- `queue_length` - Indicates to HTTP.sys how many requests to queue for an application pool before rejecting future requests. - default is 1000 - optional\n- `thirty_two_bit` - set the pool to run in 32 bit mode, valid values are true or false, default is false - optional\n\n##### Process Model Items\n\n- `max_proc` - specifies the number of worker processes associated with the pool.\n- `load_user_profile` - This property is used only when a service starts in a named user account. - Default is false - optional\n- `pool_identity` - the account identity that they app pool will run as, valid values are :SpecificUser, :NetworkService, :LocalService, :LocalSystem, :ApplicationPoolIdentity\n- `pool_username` - username for the identity for the application pool\n- `pool_password` password for the identity for the application pool is started. Default is true - optional\n- `logon_type` - Specifies the logon type for the process identity. (For additional information about [logon types](http://msdn.microsoft.com/en-us/library/aa378184%28VS.85%29.aspx), see the LogonUser Function topic on Microsoft's MSDN Web site.) - Available [:LogonBatch, :LogonService] - default is :LogonBatch - optional\n- `manual_group_membership` - Specifies whether the IIS_IUSRS group Security Identifier (SID) is added to the worker process token. When false, IIS automatically uses an application pool identity as though it were a member of the built-in IIS_IUSRS group, which has access to necessary file and system resources. When true, an application pool identity must be explicitly added to all resources that a worker process requires at runtime. - default is false - optional\n- `idle_timeout` - Specifies how long (in minutes) a worker process should run idle if no new requests are received and the worker process is not processing requests. After the allocated time passes, the worker process should request that it be shut down by the WWW service. - default is '00:20:00' - optional\n- `idle_timeout_action` - Specifies the option of suspending an idle worker process rather than terminating it. Valid values are :Terminate and :Suspend - optional\n- `shutdown_time_limit` - Specifies the time that the W3SVC service waits after it initiated a recycle. If the worker process does not shut down within the shutdownTimeLimit, it will be terminated by the W3SVC service. - default is '00:01:30' - optional\n- `startup_time_limit` - Specifies the time that IIS waits for an application pool to start. If the application pool does not startup within the startupTimeLimit, the worker process is terminated and the rapid-fail protection count is incremented. - default is '00:01:30' - optional\n- `pinging_enabled` - Specifies whether pinging is enabled for the worker process. - default is true - optional\n- `ping_interval` - Specifies the time between health-monitoring pings that the WWW service sends to a worker process - default is '00:00:30' - optional\n- `ping_response_time` - Specifies the time that a worker process is given to respond to a health-monitoring ping. After the time limit is exceeded, the WWW service terminates the worker process - default is '00:01:30' - optional\n\n##### Recycling Items\n\n- `disallow_rotation_on_config_change` - The DisallowRotationOnConfigChange property specifies whether or not the World Wide Web Publishing Service (WWW Service) should rotate worker processes in an application pool when the configuration has changed. - Default is false - optional\n- `disallow_overlapping_rotation` - Specifies whether the WWW Service should start another worker process to replace the existing worker process while that process\n- `log_event_on_recycle` - configure IIS to log an event when one or more of the following configured events cause an application pool to recycle (for additional information about [logging events] (https://technet.microsoft.com/en-us/library/cc771318%28v=ws.10%29.aspx). - default is 'Time, Requests, Schedule, Memory, IsapiUnhealthy, OnDemand, ConfigChange, PrivateMemory' - optional\n- `recycle_schedule_clear` - specifies a pool to clear all scheduled recycle times, [true,false] Default is false - optional\n- `recycle_after_time` - specifies a pool to recycle at regular time intervals, d.hh:mm:ss, d optional\n- `recycle_at_time` - schedule a pool to recycle at a specific time, d.hh:mm:ss, d optional\n- `private_mem` - specifies the amount of private memory (in kilobytes) after which you want the pool to recycle\n- `virtual_mem` - specifies the amount of virtual memory (in kilobytes) after which you want the pool to recycle\n\n#### Failure Items\n\n- `load_balancer_capabilities` - Specifies behavior when a worker process cannot be started, such as when the request queue is full or an application pool is in rapid-fail protection. - default is :HttpLevel - optional\n- `orphan_worker_process` - Specifies whether to assign a worker process to an orphan state instead of terminating it when an application pool fails. - default is false - optional\n- `orphan_action_exe` - Specifies an executable to run when the WWW service orphans a worker process (if the orphanWorkerProcess attribute is set to true). You can use the orphanActionParams attribute to send parameters to the executable. - optional\n- `orphan_action_params` - Indicates command-line parameters for the executable named by the orphanActionExe attribute. To specify the process ID of the orphaned process, use %1%. - optional\n- `rapid_fail_protection` - Setting to true instructs the WWW service to remove from service all applications that are in an application pool - default is true - optional\n- `rapid_fail_protection_interval` - Specifies the number of minutes before the failure count for a process is reset. - default is '00:05:00' - optional\n- `rapid_fail_protection_max_crashes` - Specifies the maximum number of failures that are allowed within the number of minutes specified by the rapidFailProtectionInterval attribute. - default is 5 - optional\n- `auto_shutdown_exe` - Specifies an executable to run when the WWW service shuts down an application pool. - optional\n- `auto_shutdown_params` - Specifies command-line parameters for the executable that is specified in the autoShutdownExe attribute. - optional\n\n##### CPU Items\n\n- `cpu_action` - Configures the action that IIS takes when a worker process exceeds its configured CPU limit. The action attribute is configured on a per-application pool basis. - Available options [:NoAction, :KillW3wp, :Throttle, :ThrottleUnderLoad] - default is :NoAction - optional\n- `cpu_limit` - Configures the maximum percentage of CPU time (in 1/1000ths of one percent) that the worker processes in an application pool are allowed to consume over a period of time as indicated by the resetInterval attribute. If the limit set by the limit attribute is exceeded, an event is written to the event log and an optional set of events can be triggered. These optional events are determined by the action attribute. - default is 0 - optional\n- `cpu_reset_interval` - Specifies the reset period (in minutes) for CPU monitoring and throttling limits on an application pool. When the number of minutes elapsed since the last process accounting reset equals the number specified by this property, IIS resets the CPU timers for both the logging and limit intervals. - default is '00:05:00' - optional\n- `cpu_smp_affinitized` - Specifies whether a particular worker process assigned to an application pool should also be assigned to a given CPU. - default is false - optional\n- `smp_processor_affinity_mask` - Specifies the hexadecimal processor mask for multi-processor computers, which indicates to which CPU the worker processes in an application pool should be bound. Before this property takes effect, the smpAffinitized attribute must be set to true for the application pool. - default is 4294967295 - optional\n- `smp_processor_affinity_mask_2` - Specifies the high-order DWORD hexadecimal processor mask for 64-bit multi-processor computers, which indicates to which CPU the worker processes in an application pool should be bound. Before this property takes effect, the smpAffinitized attribute must be set to true for the application pool. - default is 4294967295 - optional\n\n#### Example\n\n```ruby\n# creates a new app pool\niis_pool 'myAppPool_v1_1' do\n runtime_version \"2.0\"\n pipeline_mode :Classic\n action :add\nend\n```\n\n### iis_app\n\nCreates an application in IIS.\n\n#### Actions\n\n- `:add` - add a new application pool\n- `:delete` - delete an existing application pool\n- `:config` - configures an existing application pool\n\n#### Properties\n\n- `site_name` - name attribute. The name of the site to add this app to\n- `path` -The virtual path for this application\n- `application_pool` - The pool this application belongs to\n- `physical_path` - The physical path where this app resides.\n- `enabled_protocols` - The enabled protocols that this app provides (http, https, net.pipe, net.tcp, etc)\n\n#### Example\n\n```ruby\n# creates a new app\niis_app \"myApp\" do\n path \"/v1_1\"\n application_pool \"myAppPool_v1_1\"\n physical_path \"#{node['iis']['docroot']}/testfu/v1_1\"\n enabled_protocols \"http,net.pipe\"\n action :add\nend\n```\n\n### iis_vdir\n\nAllows easy management of IIS virtual directories (i.e. vdirs).\n\n#### Actions\n\n- :add: - add a new virtual directory\n- :delete: - delete an existing virtual directory\n- :config: - configure a virtual directory\n\n#### Attribute Parameters\n\n- `application_name`: name attribute. Specifies the name of the application attribute. This is the name of the website or application you are adding it to.\n- `path`: The virtual directory path on the site.\n- `physical_path`: The physical path of the virtual directory on the disk.\n- `username`: (optional) The username required to logon to the physical_path. If set to \"\" will clear username and password.\n- `password`: (optional) The password required to logon to the physical_path\n- `logon_method`: (optional, default: :ClearText) The method used to logon (:Interactive, :Batch, :Network, :ClearText). For more information on these types, see \"LogonUser Function\", Read more at [MSDN](http://msdn2.microsoft.com/en-us/library/aa378184.aspx)\n- `allow_sub_dir_config`: (optional, default: 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.\n\n#### Examples\n\n```ruby\n# add a virtual directory to default application\niis_vdir 'Default Web Site/' do\n action :add\n path '/Content/Test'\n physical_path 'C:\\wwwroot\\shared\\test'\nend\n```\n\n```ruby\n# add a virtual directory to an application under a site\niis_vdir 'Default Web Site/my application' do\n action :add\n path '/Content/Test'\n physical_path 'C:\\wwwroot\\shared\\test'\nend\n```\n\n```ruby\n# adds a virtual directory to default application which points to a smb share. (Remember to escape the \"\\\"'s)\niis_vdir 'Default Web Site/' do\n action :add\n path '/Content/Test'\n physical_path '\\\\\\\\sharename\\\\sharefolder\\\\1'\nend\n```\n\n```ruby\n# configure a virtual directory to have a username and password\niis_vdir 'Default Web Site/' do\n action :config\n path '/Content/Test'\n username 'domain\\myspecialuser'\n password 'myspecialpassword'\nend\n```\n\n```ruby\n# delete a virtual directory from the default application\niis_vdir 'Default Web Site/' do\n action :delete\n path '/Content/Test'\nend\n```\n\n### iis_section\n\nAllows for the locking/unlocking of sections ([listed here](http://www.iis.net/configreference) or via the command `appcmd list config \\\"\\\" /config:* /xml`)\n\nThis is valuable to allow the `web.config` of an individual application/website control it's own settings.\n\n#### Actions\n\n- `:lock`: - locks the `section` passed\n- `:unlock`: - unlocks the `section` passed\n\n#### Attribute Parameters\n\n- `section`: The name of the section to lock.\n- `returns`: The result of the `shell_out` command.\n\n#### Examples\n\n```ruby\n# Sets the IIS global windows authentication to be locked globally\niis_section 'locks global configuration of windows auth' do\n section 'system.webServer/security/authentication/windowsAuthentication'\n action :lock\nend\n```\n\n```ruby\n# Sets the IIS global Basic authentication to be locked globally\niis_section 'locks global configuration of Basic auth' do\n section 'system.webServer/security/authentication/basicAuthentication'\n action :lock\nend\n```\n\n```ruby\n# Sets the IIS global windows authentication to be unlocked globally\niis_section 'unlocked web.config globally for windows auth' do\n action :unlock\n section 'system.webServer/security/authentication/windowsAuthentication'\nend\n```\n\n```ruby\n# Sets the IIS global Basic authentication to be unlocked globally\niis_section 'unlocked web.config globally for Basic auth' do\n action :unlock\n section 'system.webServer/security/authentication/basicAuthentication'\nend\n```\n\n### iis_module\n\nManages modules globally or on a per site basis.\n\n#### Actions\n\n- `:add` - add a new module\n- `:delete` - delete a module\n- `:install` - install a native module from the filesystem (.dll)\n- `:uninstall` - uninstall a native module\n\n#### Attribute Parameters\n\n- `module_name` - The name of the module to add or delete\n- `type` - The type of module\n- `precondition` - precondition for module\n- `application` - The application or site to add the module to\n- `add` - Whether the module you install has to be globally added\n- `image` - Location of the DLL of the module to install\n\n#### Example\n\n```ruby\n# Adds a module called \"My 3rd Party Module\" to mySite/\niis_module \"My 3rd Party Module\" do\n application \"mySite/\"\n precondition \"bitness64\"\n action :add\nend\n```\n\n```ruby\n# Adds a module called \"MyModule\" to all IIS sites on the server\niis_module \"MyModule\"\n```\n\n## Usage\n\n### default recipe\n\nInstalls and configures IIS 7.0/7.5/8.0 using the default configuration.\n\n### mod_* recipes\n\nThis 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.\n\n- `mod_aspnet` - installs ASP.NET runtime components\n- `mod_aspnet45` - installs ASP.NET 4.5 runtime components\n- `mod_auth_basic` - installs Basic Authentication support\n- `mod_auth_windows` - installs Windows Authentication (authenticate clients by using NTLM or Kerberos) support\n- `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.\n- `mod_compress_static` - installs static content compression support\n- `mod_iis6_metabase_compat` - installs IIS 6 Metabase Compatibility component.\n- `mod_isapi` - installs ISAPI (Internet Server Application Programming Interface) extension and filter support.\n- `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\n- `mod_management` - installs Web server Management Console which supports management of local and remote Web servers\n- `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.\n- `mod_tracing` - installs support for tracing ASP.NET applications and failed requests.\n\nNote: 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.\n\n## Alternative Cookbooks\n\n- [Powershell based IIS Cookbook (Pre-DSC)](https://github.com/ebsco/iisposh)\n- DSC Based- [CWebAdministration](https://github.com/PowerShellOrg/cWebAdministration) / [XWebadministration](https://github.com/PowerShell/xWebAdministration) Powershell Module(s)\n\n## License and Author\n\n- Author:: Seth Chisamore ([schisamo@chef.io](mailto:schisamo@chef.io))\n- Author:: Julian Dunn ([jdunn@chef.io](mailto:jdunn@chef.io))\n- Author:: Justin Schuhmann ([jmschu02@gmail.com](mailto:jmschu02@gmail.com))\n\n```text\nCopyright 2011-2016, Chef Software, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```\n","maintainer":"Chef Software, Inc.","maintainer_email":"cookbooks@chef.io","license":"Apache 2.0","platforms":{"windows":">= 0.0.0"},"dependencies":{"windows":">= 1.34.6"},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{}} \ No newline at end of file +{"name":"iis","version":"6.7.1","description":"Installs/Configures Microsoft Internet Information Services","long_description":"# iis Cookbook\n\n[![Build status](https://ci.appveyor.com/api/projects/status/f4gnv54b97rw1pbg/branch/master?svg=true)](https://ci.appveyor.com/project/ChefWindowsCookbooks/iis/branch/master) [![Cookbook Version](https://img.shields.io/cookbook/v/iis.svg)](https://supermarket.chef.io/cookbooks/iis)\n\nInstalls and configures Microsoft Internet Information Services (IIS) 7.0 and later\n\n## Contents\n\n- [Attributes](#attributes)\n- [Resource/Provider](#resourceprovider)\n\n - [iis_root](#iis_root) Allows for easy management of the IIS Root Machine settings\n - [iis_site](#iis_site) Allows for easy management of IIS virtual sites (ie vhosts).\n - [iis_config](#iis_config) Runs a config command on your IIS instance.\n - [iis_pool](#iis_pool) Creates an application pool in IIS.\n - [iis_app](#iis_app) Creates an application in IIS.\n - [iis_vdir](#iis_vdir) Allows easy management of IIS virtual directories (i.e. vdirs).\n - [iis_section](#iis_section) Allows for the locking/unlocking of application web.config sections.\n - [iis_module](#iis_module) Manages modules globally or on a per site basis.\n\n- [Usage](#usage)\n\n - [default](#default) Default recipe\n - [mod_*](#mod_) Recipes for installing individual IIS modules (extensions).\n\n- [Alternatives](#alternative-cookbooks)\n\n- [License and Author](#license-and-author)\n\n## Requirements\n\n### Platforms\n\n- Windows Server 2008 (R1, R2)\n- Windows Server 2012 (R1, R2)\n- Windows Server 2016\n\n### Chef\n\n- Chef 12.5+\n\n### Cookbooks\n\n- windows\n\n## Attributes\n\n- `node['iis']['home']` - IIS main home directory. default is `%WINDIR%\\System32\\inetsrv`\n- `node['iis']['conf_dir']` - location where main IIS configs lives. default is `%WINDIR%\\System32\\inetsrv\\config`\n- `node['iis']['pubroot']` - . default is `%SYSTEMDRIVE%\\inetpub`\n- `node['iis']['docroot']` - IIS web site home directory. default is `%SYSTEMDRIVE%\\inetpub\\wwwroot`\n- `node['iis']['log_dir']` - location of IIS logs. default is `%SYSTEMDRIVE%\\inetpub\\logs\\LogFiles`\n- `node['iis']['cache_dir']` - location of cached data. default is `%SYSTEMDRIVE%\\inetpub\\temp`\n\n## Resource/Provider\n\n### iis_root\n\nAllows for easy management of the IIS Root Machine settings\n\n#### Actions\n\n`default` = `:config`\n\n- `:add` - only does addition operations will not delete anything to an Array object\n- `:delete` - only does deletion operations will not add anything to an Array object\n- `:config` - does both addition and deletion make sure your Array objects contain everything you want\n\n#### Properties\n\n- `default_documents_enabled` - Enables or disables default_documents for the root machine, Valid Values: true, false default: `true`\n- `default_documents` - The items you want to set as the default document collection, only used during `:config`. Array of strings, default: `['Default.htm', 'Default.asp', 'index.htm', 'index.html', 'iisstart.htm', 'default.aspx']`\n- `mime_maps` - The items you want to set as the mime-maps or mime-types collection, only used during `:config`. Array of strings, default:\n\n ```ruby\n [\"fileExtension='.323',mimeType='text/h323'\", \"fileExtension='.3g2',mimeType='video/3gpp2'\", \"fileExtension='.3gp2',mimeType='video/3gpp2'\", \"fileExtension='.3gp',mimeType='video/3gpp'\", \"fileExtension='.3gpp',mimeType='video/3gpp'\", \"fileExtension='.aaf',mimeType='application/octet-stream'\", \"fileExtension='.aac',mimeType='audio/aac'\", \"fileExtension='.aca',mimeType='application/octet-stream'\", \"fileExtension='.accdb',mimeType='application/msaccess'\", \"fileExtension='.accde',mimeType='application/msaccess'\", \"fileExtension='.accdt',mimeType='application/msaccess'\", \"fileExtension='.acx',mimeType='application/internet-property-stream'\", \"fileExtension='.adt',mimeType='audio/vnd.dlna.adts'\", \"fileExtension='.adts',mimeType='audio/vnd.dlna.adts'\", \"fileExtension='.afm',mimeType='application/octet-stream'\", \"fileExtension='.ai',mimeType='application/postscript'\", \"fileExtension='.aif',mimeType='audio/x-aiff'\", \"fileExtension='.aifc',mimeType='audio/aiff'\", \"fileExtension='.aiff',mimeType='audio/aiff'\", \"fileExtension='.application',mimeType='application/x-ms-application'\", \"fileExtension='.art',mimeType='image/x-jg'\", \"fileExtension='.asd',mimeType='application/octet-stream'\", \"fileExtension='.asf',mimeType='video/x-ms-asf'\", \"fileExtension='.asi',mimeType='application/octet-stream'\", \"fileExtension='.asm',mimeType='text/plain'\", \"fileExtension='.asr',mimeType='video/x-ms-asf'\", \"fileExtension='.asx',mimeType='video/x-ms-asf'\", \"fileExtension='.atom',mimeType='application/atom+xml'\", \"fileExtension='.au',mimeType='audio/basic'\", \"fileExtension='.avi',mimeType='video/avi'\", \"fileExtension='.axs',mimeType='application/olescript'\", \"fileExtension='.bas',mimeType='text/plain'\", \"fileExtension='.bcpio',mimeType='application/x-bcpio'\", \"fileExtension='.bin',mimeType='application/octet-stream'\", \"fileExtension='.bmp',mimeType='image/bmp'\", \"fileExtension='.c',mimeType='text/plain'\", \"fileExtension='.cab',mimeType='application/vnd.ms-cab-compressed'\", \"fileExtension='.calx',mimeType='application/vnd.ms-office.calx'\", \"fileExtension='.cat',mimeType='application/vnd.ms-pki.seccat'\", \"fileExtension='.cdf',mimeType='application/x-cdf'\", \"fileExtension='.chm',mimeType='application/octet-stream'\", \"fileExtension='.class',mimeType='application/x-java-applet'\", \"fileExtension='.clp',mimeType='application/x-msclip'\", \"fileExtension='.cmx',mimeType='image/x-cmx'\", \"fileExtension='.cnf',mimeType='text/plain'\", \"fileExtension='.cod',mimeType='image/cis-cod'\", \"fileExtension='.cpio',mimeType='application/x-cpio'\", \"fileExtension='.cpp',mimeType='text/plain'\", \"fileExtension='.crd',mimeType='application/x-mscardfile'\", \"fileExtension='.crl',mimeType='application/pkix-crl'\", \"fileExtension='.crt',mimeType='application/x-x509-ca-cert'\", \"fileExtension='.csh',mimeType='application/x-csh'\", \"fileExtension='.css',mimeType='text/css'\", \"fileExtension='.csv',mimeType='application/octet-stream'\", \"fileExtension='.cur',mimeType='application/octet-stream'\", \"fileExtension='.dcr',mimeType='application/x-director'\", \"fileExtension='.deploy',mimeType='application/octet-stream'\", \"fileExtension='.der',mimeType='application/x-x509-ca-cert'\", \"fileExtension='.dib',mimeType='image/bmp'\", \"fileExtension='.dir',mimeType='application/x-director'\", \"fileExtension='.disco',mimeType='text/xml'\", \"fileExtension='.dll',mimeType='application/x-msdownload'\", \"fileExtension='.dll.config',mimeType='text/xml'\", \"fileExtension='.dlm',mimeType='text/dlm'\", \"fileExtension='.doc',mimeType='application/msword'\", \"fileExtension='.docm',mimeType='application/vnd.ms-word.document.macroEnabled.12'\", \"fileExtension='.docx',mimeType='application/vnd.openxmlformats-officedocument.wordprocessingml.document'\", \"fileExtension='.dot',mimeType='application/msword'\", \"fileExtension='.dotm',mimeType='application/vnd.ms-word.template.macroEnabled.12'\", \"fileExtension='.dotx',mimeType='application/vnd.openxmlformats-officedocument.wordprocessingml.template'\", \"fileExtension='.dsp',mimeType='application/octet-stream'\", \"fileExtension='.dtd',mimeType='text/xml'\", \"fileExtension='.dvi',mimeType='application/x-dvi'\", \"fileExtension='.dvr-ms',mimeType='video/x-ms-dvr'\", \"fileExtension='.dwf',mimeType='drawing/x-dwf'\", \"fileExtension='.dwp',mimeType='application/octet-stream'\", \"fileExtension='.dxr',mimeType='application/x-director'\", \"fileExtension='.eml',mimeType='message/rfc822'\", \"fileExtension='.emz',mimeType='application/octet-stream'\", \"fileExtension='.eot',mimeType='application/vnd.ms-fontobject'\", \"fileExtension='.eps',mimeType='application/postscript'\", \"fileExtension='.etx',mimeType='text/x-setext'\", \"fileExtension='.evy',mimeType='application/envoy'\", \"fileExtension='.exe',mimeType='application/octet-stream'\", \"fileExtension='.exe.config',mimeType='text/xml'\", \"fileExtension='.fdf',mimeType='application/vnd.fdf'\", \"fileExtension='.fif',mimeType='application/fractals'\", \"fileExtension='.fla',mimeType='application/octet-stream'\", \"fileExtension='.flr',mimeType='x-world/x-vrml'\", \"fileExtension='.flv',mimeType='video/x-flv'\", \"fileExtension='.gif',mimeType='image/gif'\", \"fileExtension='.gtar',mimeType='application/x-gtar'\", \"fileExtension='.gz',mimeType='application/x-gzip'\", \"fileExtension='.h',mimeType='text/plain'\", \"fileExtension='.hdf',mimeType='application/x-hdf'\", \"fileExtension='.hdml',mimeType='text/x-hdml'\", \"fileExtension='.hhc',mimeType='application/x-oleobject'\", \"fileExtension='.hhk',mimeType='application/octet-stream'\", \"fileExtension='.hhp',mimeType='application/octet-stream'\", \"fileExtension='.hlp',mimeType='application/winhlp'\", \"fileExtension='.hqx',mimeType='application/mac-binhex40'\", \"fileExtension='.hta',mimeType='application/hta'\", \"fileExtension='.htc',mimeType='text/x-component'\", \"fileExtension='.htm',mimeType='text/html'\", \"fileExtension='.html',mimeType='text/html'\", \"fileExtension='.htt',mimeType='text/webviewhtml'\", \"fileExtension='.hxt',mimeType='text/html'\", \"fileExtension='.ico',mimeType='image/x-icon'\", \"fileExtension='.ics',mimeType='text/calendar'\", \"fileExtension='.ief',mimeType='image/ief'\", \"fileExtension='.iii',mimeType='application/x-iphone'\", \"fileExtension='.inf',mimeType='application/octet-stream'\", \"fileExtension='.ins',mimeType='application/x-internet-signup'\", \"fileExtension='.isp',mimeType='application/x-internet-signup'\", \"fileExtension='.IVF',mimeType='video/x-ivf'\", \"fileExtension='.jar',mimeType='application/java-archive'\", \"fileExtension='.java',mimeType='application/octet-stream'\", \"fileExtension='.jck',mimeType='application/liquidmotion'\", \"fileExtension='.jcz',mimeType='application/liquidmotion'\", \"fileExtension='.jfif',mimeType='image/pjpeg'\", \"fileExtension='.jpb',mimeType='application/octet-stream'\", \"fileExtension='.jpe',mimeType='image/jpeg'\", \"fileExtension='.jpeg',mimeType='image/jpeg'\", \"fileExtension='.jpg',mimeType='image/jpeg'\", \"fileExtension='.js',mimeType='application/javascript'\", \"fileExtension='.json',mimeType='application/json'\", \"fileExtension='.jsx',mimeType='text/jscript'\", \"fileExtension='.latex',mimeType='application/x-latex'\", \"fileExtension='.lit',mimeType='application/x-ms-reader'\", \"fileExtension='.lpk',mimeType='application/octet-stream'\", \"fileExtension='.lsf',mimeType='video/x-la-asf'\", \"fileExtension='.lsx',mimeType='video/x-la-asf'\", \"fileExtension='.lzh',mimeType='application/octet-stream'\", \"fileExtension='.m13',mimeType='application/x-msmediaview'\", \"fileExtension='.m14',mimeType='application/x-msmediaview'\", \"fileExtension='.m1v',mimeType='video/mpeg'\", \"fileExtension='.m2ts',mimeType='video/vnd.dlna.mpeg-tts'\", \"fileExtension='.m3u',mimeType='audio/x-mpegurl'\", \"fileExtension='.m4a',mimeType='audio/mp4'\", \"fileExtension='.m4v',mimeType='video/mp4'\", \"fileExtension='.man',mimeType='application/x-troff-man'\", \"fileExtension='.manifest',mimeType='application/x-ms-manifest'\", \"fileExtension='.map',mimeType='text/plain'\", \"fileExtension='.mdb',mimeType='application/x-msaccess'\", \"fileExtension='.mdp',mimeType='application/octet-stream'\", \"fileExtension='.me',mimeType='application/x-troff-me'\", \"fileExtension='.mht',mimeType='message/rfc822'\", \"fileExtension='.mhtml',mimeType='message/rfc822'\", \"fileExtension='.mid',mimeType='audio/mid'\", \"fileExtension='.midi',mimeType='audio/mid'\", \"fileExtension='.mix',mimeType='application/octet-stream'\", \"fileExtension='.mmf',mimeType='application/x-smaf'\", \"fileExtension='.mno',mimeType='text/xml'\", \"fileExtension='.mny',mimeType='application/x-msmoney'\", \"fileExtension='.mov',mimeType='video/quicktime'\", \"fileExtension='.movie',mimeType='video/x-sgi-movie'\", \"fileExtension='.mp2',mimeType='video/mpeg'\", \"fileExtension='.mp3',mimeType='audio/mpeg'\", \"fileExtension='.mp4',mimeType='video/mp4'\", \"fileExtension='.mp4v',mimeType='video/mp4'\", \"fileExtension='.mpa',mimeType='video/mpeg'\", \"fileExtension='.mpe',mimeType='video/mpeg'\", \"fileExtension='.mpeg',mimeType='video/mpeg'\", \"fileExtension='.mpg',mimeType='video/mpeg'\", \"fileExtension='.mpp',mimeType='application/vnd.ms-project'\", \"fileExtension='.mpv2',mimeType='video/mpeg'\", \"fileExtension='.ms',mimeType='application/x-troff-ms'\", \"fileExtension='.msi',mimeType='application/octet-stream'\", \"fileExtension='.mso',mimeType='application/octet-stream'\", \"fileExtension='.mvb',mimeType='application/x-msmediaview'\", \"fileExtension='.mvc',mimeType='application/x-miva-compiled'\", \"fileExtension='.nc',mimeType='application/x-netcdf'\", \"fileExtension='.nsc',mimeType='video/x-ms-asf'\", \"fileExtension='.nws',mimeType='message/rfc822'\", \"fileExtension='.ocx',mimeType='application/octet-stream'\", \"fileExtension='.oda',mimeType='application/oda'\", \"fileExtension='.odc',mimeType='text/x-ms-odc'\", \"fileExtension='.ods',mimeType='application/oleobject'\", \"fileExtension='.oga',mimeType='audio/ogg'\", \"fileExtension='.ogg',mimeType='video/ogg'\", \"fileExtension='.ogv',mimeType='video/ogg'\", \"fileExtension='.one',mimeType='application/onenote'\", \"fileExtension='.onea',mimeType='application/onenote'\", \"fileExtension='.onetoc',mimeType='application/onenote'\", \"fileExtension='.onetoc2',mimeType='application/onenote'\", \"fileExtension='.onetmp',mimeType='application/onenote'\", \"fileExtension='.onepkg',mimeType='application/onenote'\", \"fileExtension='.osdx',mimeType='application/opensearchdescription+xml'\", \"fileExtension='.otf',mimeType='font/otf'\", \"fileExtension='.p10',mimeType='application/pkcs10'\", \"fileExtension='.p12',mimeType='application/x-pkcs12'\", \"fileExtension='.p7b',mimeType='application/x-pkcs7-certificates'\", \"fileExtension='.p7c',mimeType='application/pkcs7-mime'\", \"fileExtension='.p7m',mimeType='application/pkcs7-mime'\", \"fileExtension='.p7r',mimeType='application/x-pkcs7-certreqresp'\", \"fileExtension='.p7s',mimeType='application/pkcs7-signature'\", \"fileExtension='.pbm',mimeType='image/x-portable-bitmap'\", \"fileExtension='.pcx',mimeType='application/octet-stream'\", \"fileExtension='.pcz',mimeType='application/octet-stream'\", \"fileExtension='.pdf',mimeType='application/pdf'\", \"fileExtension='.pfb',mimeType='application/octet-stream'\", \"fileExtension='.pfm',mimeType='application/octet-stream'\", \"fileExtension='.pfx',mimeType='application/x-pkcs12'\", \"fileExtension='.pgm',mimeType='image/x-portable-graymap'\", \"fileExtension='.pko',mimeType='application/vnd.ms-pki.pko'\", \"fileExtension='.pma',mimeType='application/x-perfmon'\", \"fileExtension='.pmc',mimeType='application/x-perfmon'\", \"fileExtension='.pml',mimeType='application/x-perfmon'\", \"fileExtension='.pmr',mimeType='application/x-perfmon'\", \"fileExtension='.pmw',mimeType='application/x-perfmon'\", \"fileExtension='.png',mimeType='image/png'\", \"fileExtension='.pnm',mimeType='image/x-portable-anymap'\", \"fileExtension='.pnz',mimeType='image/png'\", \"fileExtension='.pot',mimeType='application/vnd.ms-powerpoint'\", \"fileExtension='.potm',mimeType='application/vnd.ms-powerpoint.template.macroEnabled.12'\", \"fileExtension='.potx',mimeType='application/vnd.openxmlformats-officedocument.presentationml.template'\", \"fileExtension='.ppam',mimeType='application/vnd.ms-powerpoint.addin.macroEnabled.12'\", \"fileExtension='.ppm',mimeType='image/x-portable-pixmap'\", \"fileExtension='.pps',mimeType='application/vnd.ms-powerpoint'\", \"fileExtension='.ppsm',mimeType='application/vnd.ms-powerpoint.slideshow.macroEnabled.12'\", \"fileExtension='.ppsx',mimeType='application/vnd.openxmlformats-officedocument.presentationml.slideshow'\", \"fileExtension='.ppt',mimeType='application/vnd.ms-powerpoint'\", \"fileExtension='.pptm',mimeType='application/vnd.ms-powerpoint.presentation.macroEnabled.12'\", \"fileExtension='.pptx',mimeType='application/vnd.openxmlformats-officedocument.presentationml.presentation'\", \"fileExtension='.prf',mimeType='application/pics-rules'\", \"fileExtension='.prm',mimeType='application/octet-stream'\", \"fileExtension='.prx',mimeType='application/octet-stream'\", \"fileExtension='.ps',mimeType='application/postscript'\", \"fileExtension='.psd',mimeType='application/octet-stream'\", \"fileExtension='.psm',mimeType='application/octet-stream'\", \"fileExtension='.psp',mimeType='application/octet-stream'\", \"fileExtension='.pub',mimeType='application/x-mspublisher'\", \"fileExtension='.qt',mimeType='video/quicktime'\", \"fileExtension='.qtl',mimeType='application/x-quicktimeplayer'\", \"fileExtension='.qxd',mimeType='application/octet-stream'\", \"fileExtension='.ra',mimeType='audio/x-pn-realaudio'\", \"fileExtension='.ram',mimeType='audio/x-pn-realaudio'\", \"fileExtension='.rar',mimeType='application/octet-stream'\", \"fileExtension='.ras',mimeType='image/x-cmu-raster'\", \"fileExtension='.rf',mimeType='image/vnd.rn-realflash'\", \"fileExtension='.rgb',mimeType='image/x-rgb'\", \"fileExtension='.rm',mimeType='application/vnd.rn-realmedia'\", \"fileExtension='.rmi',mimeType='audio/mid'\", \"fileExtension='.roff',mimeType='application/x-troff'\", \"fileExtension='.rpm',mimeType='audio/x-pn-realaudio-plugin'\", \"fileExtension='.rtf',mimeType='application/rtf'\", \"fileExtension='.rtx',mimeType='text/richtext'\", \"fileExtension='.scd',mimeType='application/x-msschedule'\", \"fileExtension='.sct',mimeType='text/scriptlet'\", \"fileExtension='.sea',mimeType='application/octet-stream'\", \"fileExtension='.setpay',mimeType='application/set-payment-initiation'\", \"fileExtension='.setreg',mimeType='application/set-registration-initiation'\", \"fileExtension='.sgml',mimeType='text/sgml'\", \"fileExtension='.sh',mimeType='application/x-sh'\", \"fileExtension='.shar',mimeType='application/x-shar'\", \"fileExtension='.sit',mimeType='application/x-stuffit'\", \"fileExtension='.sldm',mimeType='application/vnd.ms-powerpoint.slide.macroEnabled.12'\", \"fileExtension='.sldx',mimeType='application/vnd.openxmlformats-officedocument.presentationml.slide'\", \"fileExtension='.smd',mimeType='audio/x-smd'\", \"fileExtension='.smi',mimeType='application/octet-stream'\", \"fileExtension='.smx',mimeType='audio/x-smd'\", \"fileExtension='.smz',mimeType='audio/x-smd'\", \"fileExtension='.snd',mimeType='audio/basic'\", \"fileExtension='.snp',mimeType='application/octet-stream'\", \"fileExtension='.spc',mimeType='application/x-pkcs7-certificates'\", \"fileExtension='.spl',mimeType='application/futuresplash'\", \"fileExtension='.spx',mimeType='audio/ogg'\", \"fileExtension='.src',mimeType='application/x-wais-source'\", \"fileExtension='.ssm',mimeType='application/streamingmedia'\", \"fileExtension='.sst',mimeType='application/vnd.ms-pki.certstore'\", \"fileExtension='.stl',mimeType='application/vnd.ms-pki.stl'\", \"fileExtension='.sv4cpio',mimeType='application/x-sv4cpio'\", \"fileExtension='.sv4crc',mimeType='application/x-sv4crc'\", \"fileExtension='.svg',mimeType='image/svg+xml'\", \"fileExtension='.svgz',mimeType='image/svg+xml'\", \"fileExtension='.swf',mimeType='application/x-shockwave-flash'\", \"fileExtension='.t',mimeType='application/x-troff'\", \"fileExtension='.tar',mimeType='application/x-tar'\", \"fileExtension='.tcl',mimeType='application/x-tcl'\", \"fileExtension='.tex',mimeType='application/x-tex'\", \"fileExtension='.texi',mimeType='application/x-texinfo'\", \"fileExtension='.texinfo',mimeType='application/x-texinfo'\", \"fileExtension='.tgz',mimeType='application/x-compressed'\", \"fileExtension='.thmx',mimeType='application/vnd.ms-officetheme'\", \"fileExtension='.thn',mimeType='application/octet-stream'\", \"fileExtension='.tif',mimeType='image/tiff'\", \"fileExtension='.tiff',mimeType='image/tiff'\", \"fileExtension='.toc',mimeType='application/octet-stream'\", \"fileExtension='.tr',mimeType='application/x-troff'\", \"fileExtension='.trm',mimeType='application/x-msterminal'\", \"fileExtension='.ts',mimeType='video/vnd.dlna.mpeg-tts'\", \"fileExtension='.tsv',mimeType='text/tab-separated-values'\", \"fileExtension='.ttf',mimeType='application/octet-stream'\", \"fileExtension='.tts',mimeType='video/vnd.dlna.mpeg-tts'\", \"fileExtension='.txt',mimeType='text/plain'\", \"fileExtension='.u32',mimeType='application/octet-stream'\", \"fileExtension='.uls',mimeType='text/iuls'\", \"fileExtension='.ustar',mimeType='application/x-ustar'\", \"fileExtension='.vbs',mimeType='text/vbscript'\", \"fileExtension='.vcf',mimeType='text/x-vcard'\", \"fileExtension='.vcs',mimeType='text/plain'\", \"fileExtension='.vdx',mimeType='application/vnd.ms-visio.viewer'\", \"fileExtension='.vml',mimeType='text/xml'\", \"fileExtension='.vsd',mimeType='application/vnd.visio'\", \"fileExtension='.vss',mimeType='application/vnd.visio'\", \"fileExtension='.vst',mimeType='application/vnd.visio'\", \"fileExtension='.vsto',mimeType='application/x-ms-vsto'\", \"fileExtension='.vsw',mimeType='application/vnd.visio'\", \"fileExtension='.vsx',mimeType='application/vnd.visio'\", \"fileExtension='.vtx',mimeType='application/vnd.visio'\", \"fileExtension='.wav',mimeType='audio/wav'\", \"fileExtension='.wax',mimeType='audio/x-ms-wax'\", \"fileExtension='.wbmp',mimeType='image/vnd.wap.wbmp'\", \"fileExtension='.wcm',mimeType='application/vnd.ms-works'\", \"fileExtension='.wdb',mimeType='application/vnd.ms-works'\", \"fileExtension='.webm',mimeType='video/webm'\", \"fileExtension='.wks',mimeType='application/vnd.ms-works'\", \"fileExtension='.wm',mimeType='video/x-ms-wm'\", \"fileExtension='.wma',mimeType='audio/x-ms-wma'\", \"fileExtension='.wmd',mimeType='application/x-ms-wmd'\", \"fileExtension='.wmf',mimeType='application/x-msmetafile'\", \"fileExtension='.wml',mimeType='text/vnd.wap.wml'\", \"fileExtension='.wmlc',mimeType='application/vnd.wap.wmlc'\", \"fileExtension='.wmls',mimeType='text/vnd.wap.wmlscript'\", \"fileExtension='.wmlsc',mimeType='application/vnd.wap.wmlscriptc'\", \"fileExtension='.wmp',mimeType='video/x-ms-wmp'\", \"fileExtension='.wmv',mimeType='video/x-ms-wmv'\", \"fileExtension='.wmx',mimeType='video/x-ms-wmx'\", \"fileExtension='.wmz',mimeType='application/x-ms-wmz'\", \"fileExtension='.woff',mimeType='font/x-woff'\", \"fileExtension='.wps',mimeType='application/vnd.ms-works'\", \"fileExtension='.wri',mimeType='application/x-mswrite'\", \"fileExtension='.wrl',mimeType='x-world/x-vrml'\", \"fileExtension='.wrz',mimeType='x-world/x-vrml'\", \"fileExtension='.wsdl',mimeType='text/xml'\", \"fileExtension='.wtv',mimeType='video/x-ms-wtv'\", \"fileExtension='.wvx',mimeType='video/x-ms-wvx'\", \"fileExtension='.x',mimeType='application/directx'\", \"fileExtension='.xaf',mimeType='x-world/x-vrml'\", \"fileExtension='.xaml',mimeType='application/xaml+xml'\", \"fileExtension='.xap',mimeType='application/x-silverlight-app'\", \"fileExtension='.xbap',mimeType='application/x-ms-xbap'\", \"fileExtension='.xbm',mimeType='image/x-xbitmap'\", \"fileExtension='.xdr',mimeType='text/plain'\", \"fileExtension='.xht',mimeType='application/xhtml+xml'\", \"fileExtension='.xhtml',mimeType='application/xhtml+xml'\", \"fileExtension='.xla',mimeType='application/vnd.ms-excel'\", \"fileExtension='.xlam',mimeType='application/vnd.ms-excel.addin.macroEnabled.12'\", \"fileExtension='.xlc',mimeType='application/vnd.ms-excel'\", \"fileExtension='.xlm',mimeType='application/vnd.ms-excel'\", \"fileExtension='.xls',mimeType='application/vnd.ms-excel'\", \"fileExtension='.xlsb',mimeType='application/vnd.ms-excel.sheet.binary.macroEnabled.12'\", \"fileExtension='.xlsm',mimeType='application/vnd.ms-excel.sheet.macroEnabled.12'\", \"fileExtension='.xlsx',mimeType='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'\", \"fileExtension='.xlt',mimeType='application/vnd.ms-excel'\", \"fileExtension='.xltm',mimeType='application/vnd.ms-excel.template.macroEnabled.12'\", \"fileExtension='.xltx',mimeType='application/vnd.openxmlformats-officedocument.spreadsheetml.template'\", \"fileExtension='.xlw',mimeType='application/vnd.ms-excel'\", \"fileExtension='.xml',mimeType='text/xml'\", \"fileExtension='.xof',mimeType='x-world/x-vrml'\", \"fileExtension='.xpm',mimeType='image/x-xpixmap'\", \"fileExtension='.xps',mimeType='application/vnd.ms-xpsdocument'\", \"fileExtension='.xsd',mimeType='text/xml'\", \"fileExtension='.xsf',mimeType='text/xml'\", \"fileExtension='.xsl',mimeType='text/xml'\", \"fileExtension='.xslt',mimeType='text/xml'\", \"fileExtension='.xsn',mimeType='application/octet-stream'\", \"fileExtension='.xtp',mimeType='application/octet-stream'\", \"fileExtension='.xwd',mimeType='image/x-xwindowdump'\", \"fileExtension='.z',mimeType='application/x-compress'\", \"fileExtension='.zip',mimeType='application/x-zip-compressed'\"]\n ```\n\n- `add_default_documents` - The items you want to add to the default document collection, only used during `:add`. Array of strings, default: `[]`\n\n- `add_mime_maps` - The items you want to add to the mime-map/mime-type collection, only used during `:add`. Array of strings, default: `[]`\n\n- `delete_default_documents` - The items you want to delete from the default document collection, only used during `:delete`. Array of strings, default: `[]`\n\n- `delete_mime_maps` - The items you want to delete from the mime-map/mime-type collection, only used during `:delete`. Array of strings, default: `[]`\n\n#### Examples\n\n```ruby\n# Add foo.html to default documents, and add '.dmg' as mime type extension at root level\niis_root 'add stuff' do\n add_default_documents ['foo.html']\n add_mime_maps [\"fileExtension='.dmg',mimeType='application/octet-stream'\"]\n action :add\nend\n```\n\n```ruby\n# Remove index.html from default document and .323 as a mime type at root level\niis_root 'delete stuff' do\n delete_default_documents ['index.html']\n delete_mime_maps [\"fileExtension='.323',mimeType='text/h323'\"]\n action :delete\nend\n```\n\n### iis_site\n\nAllows for easy management of IIS virtual sites (ie vhosts).\n\n#### Actions\n\n- `:add` - add a new virtual site\n- `:config` - apply configuration to an existing virtual site\n- `:delete` - delete an existing virtual site\n- `:start` - start a virtual site\n- `:stop` - stop a virtual site\n- `:restart` - restart a virtual site\n\n#### Properties\n\n- `site_name` - name attribute.\n- `site_id` - if not given IIS generates a unique ID for the site\n- `path` - IIS will create a root application and a root virtual directory mapped to this specified local path\n- `protocol` - http protocol type the site should respond to. valid values are :http, :https. default is :http\n- `port` - port site will listen on. default is 80\n- `host_header` - host header (also known as domains or host names) the site should map to. default is all host headers\n- `options` - additional options to configure the site\n- `bindings` - Advanced options to configure the information required for requests to communicate with a Web site. See for parameter format. When binding is used, port protocol and host_header should not be used.\n- `application_pool` - set the application pool of the site\n- `options` - support for additional options -logDir, -limits, -ftpServer, etc...\n- `log_directory` - specifies the logging directory, where the log file and logging-related support files are stored.\n- `log_period` - specifies how often iis creates a new log file\n- `log_truncsize` - specifies the maximum size of the log file (in bytes) after which to create a new log file.\n\n#### Examples\n\n```ruby\n# stop and delete the default site\niis_site 'Default Web Site' do\n action [:stop, :delete]\nend\n```\n\n```ruby\n# create and start a new site that maps to\n# the physical location C:\\inetpub\\wwwroot\\testfu\n# first the physical location must exist\ndirectory \"#{node['iis']['docroot']}/testfu\" do\n action :create\nend\n\n# now create and start the site (note this will use the default application pool which must exist)\niis_site 'Testfu Site' do\n protocol :http\n port 80\n path \"#{node['iis']['docroot']}/testfu\"\n action [:add,:start]\nend\n```\n\n```ruby\n# do the same but map to testfu.chef.io domain\n# first the physical location must exist\ndirectory \"#{node['iis']['docroot']}/testfu\" do\n action :create\nend\n\n# now create and start the site (note this will use the default application pool which must exist)\niis_site 'Testfu Site' do\n protocol :http\n port 80\n path \"#{node['iis']['docroot']}/testfu\"\n host_header \"testfu.chef.io\"\n action [:add,:start]\nend\n```\n\n```ruby\n# create and start a new site that maps to\n# the physical C:\\inetpub\\wwwroot\\testfu\n# first the physical location must exist\ndirectory \"#{node['iis']['docroot']}/testfu\" do\n action :create\nend\n\n# also adds bindings to http and https\n# binding http to the ip address 10.12.0.136,\n# the port 80, and the host header www.domain.com\n# also binding https to any ip address,\n# the port 443, and the host header www.domain.com\n# now create and start the site (note this will use the default application pool which must exist)\niis_site 'FooBar Site' do\n bindings \"http/10.12.0.136:80:www.domain.com,https/*:443:www.domain.com\n path \"#{node['iis']['docroot']}/testfu\"\n action [:add,:start]\nend\n```\n\n### iis_config\n\nRuns a config command on your IIS instance.\n\n#### Actions\n\n- `:set` - Edit configuration section (appcmd set config)\n- `:clear` - Clear the section configuration (appcmd clear config)\n\n#### Properties\n\n- `cfg_cmd` - name attribute. What ever command you would pass in after \"appcmd.exe set config\"\n\n#### Example\n\n```ruby\n# Sets up logging\niis_config \"/section:system.applicationHost/sites /siteDefaults.logfile.directory:\\\"D:\\\\logs\\\"\" do\n action :set\nend\n```\n\n```ruby\n# Increase file upload size for 'MySite'\niis_config \"\\\"MySite\\\" /section:requestfiltering /requestlimits.maxallowedcontentlength:50000000\" do\n action :set\nend\n```\n\n```ruby\n# Set IUSR username and password authentication\niis_config \"\\\"MyWebsite/aSite\\\" -section:system.webServer/security/authentication/anonymousAuthentication /enabled:\\\"True\\\" /userName:\\\"IUSR_foobar\\\" /password:\\\"p@assword\\\" /commit:apphost\" do\n action :set\nend\n```\n\n```ruby\n# Authenticate with application pool\niis_config \"\\\"MyWebsite/aSite\\\" -section:system.webServer/security/authentication/anonymousAuthentication /enabled:\\\"True\\\" /userName:\\\"\\\" /commit:apphost\" do\n action :set\nend\n```\n\n```ruby\n# Loads an array of commands from the node\ncfg_cmds = node['iis']['cfg_cmd']\ncfg_cmds.each do |cmd|\n iis_config \"#{cmd}\" do\n action :set\n end\nend\n```\n\n```ruby\n# Add static machine key at site level\niis_config \"MySite /commit:site /section:machineKey /validation:AES /validationKey:AAAAAA /decryptionKey:ZZZZZ\" do\n action :set\nend\n```\n\n```ruby\n# Remove machine key\niis_config \"MySite /commit:site /section:machineKey\" do\n action :clear\nend\n```\n\n### iis_pool\n\nCreates an application pool in IIS.\n\n#### Actions\n\n- `:add` - add a new application pool\n- `:config` - apply configuration to an existing application pool\n- `:delete` - delete an existing application pool\n- `:start` - start a application pool\n- `:stop` - stop a application pool\n- `:restart` - restart a application pool\n- `:recycle` - recycle an application pool\n\n#### Properties\n\n##### Root Items\n\n- `name` - name attribute. Specifies the name of the pool to create.\n- `runtime_version` - specifies what .NET version of the runtime to use.\n- `pipeline_mode` - specifies what pipeline mode to create the pool with, valid values are :Integrated or :Classic, the default is :Integrated\n- `no_managed_code` - allow Unmanaged Code in setting up IIS app pools is shutting down. - default is true - optional\n\n##### Add Items\n\n- `start_mode` - Specifies the startup type for the application pool - default :OnDemand (:OnDemand, :AlwaysRunning) - optional\n- `auto_start` - When true, indicates to the World Wide Web Publishing Service (W3SVC) that the application pool should be automatically started when it is created or when IIS is started. - boolean: default true - optional\n- `queue_length` - Indicates to HTTP.sys how many requests to queue for an application pool before rejecting future requests. - default is 1000 - optional\n- `thirty_two_bit` - set the pool to run in 32 bit mode, valid values are true or false, default is false - optional\n\n##### Process Model Items\n\n- `max_processes` - specifies the number of worker processes associated with the pool.\n- `load_user_profile` - This property is used only when a service starts in a named user account. - Default is false - optional\n- `identity_type` - the account identity that they app pool will run as, valid values are :SpecificUser, :NetworkService, :LocalService, :LocalSystem, :ApplicationPoolIdentity\n- `username` - username for the identity for the application pool\n- `password` password for the identity for the application pool is started. Default is true - optional\n- `logon_type` - Specifies the logon type for the process identity. (For additional information about [logon types](http://msdn.microsoft.com/en-us/library/aa378184%28VS.85%29.aspx), see the LogonUser Function topic on Microsoft's MSDN Web site.) - Available [:LogonBatch, :LogonService] - default is :LogonBatch - optional\n- `manual_group_membership` - Specifies whether the IIS_IUSRS group Security Identifier (SID) is added to the worker process token. When false, IIS automatically uses an application pool identity as though it were a member of the built-in IIS_IUSRS group, which has access to necessary file and system resources. When true, an application pool identity must be explicitly added to all resources that a worker process requires at runtime. - default is false - optional\n- `idle_timeout` - Specifies how long (in minutes) a worker process should run idle if no new requests are received and the worker process is not processing requests. After the allocated time passes, the worker process should request that it be shut down by the WWW service. - default is '00:20:00' - optional\n- `idle_timeout_action` - Specifies the option of suspending an idle worker process rather than terminating it. Valid values are :Terminate and :Suspend - optional\n- `shutdown_time_limit` - Specifies the time that the W3SVC service waits after it initiated a recycle. If the worker process does not shut down within the shutdownTimeLimit, it will be terminated by the W3SVC service. - default is '00:01:30' - optional\n- `startup_time_limit` - Specifies the time that IIS waits for an application pool to start. If the application pool does not startup within the startupTimeLimit, the worker process is terminated and the rapid-fail protection count is incremented. - default is '00:01:30' - optional\n- `pinging_enabled` - Specifies whether pinging is enabled for the worker process. - default is true - optional\n- `ping_interval` - Specifies the time between health-monitoring pings that the WWW service sends to a worker process - default is '00:00:30' - optional\n- `ping_response_time` - Specifies the time that a worker process is given to respond to a health-monitoring ping. After the time limit is exceeded, the WWW service terminates the worker process - default is '00:01:30' - optional\n\n##### Recycling Items\n\n- `disallow_rotation_on_config_change` - The DisallowRotationOnConfigChange property specifies whether or not the World Wide Web Publishing Service (WWW Service) should rotate worker processes in an application pool when the configuration has changed. - Default is false - optional\n- `disallow_overlapping_rotation` - Specifies whether the WWW Service should start another worker process to replace the existing worker process while that process\n- `log_event_on_recycle` - configure IIS to log an event when one or more of the following configured events cause an application pool to recycle (for additional information about [logging events] (). - default is 'Time, Requests, Schedule, Memory, IsapiUnhealthy, OnDemand, ConfigChange, PrivateMemory' - optional\n- `recycle_schedule_clear` - specifies a pool to clear all scheduled recycle times, [true,false] Default is false - optional\n- `recycle_after_time` - specifies a pool to recycle at regular time intervals, d.hh:mm:ss, d optional\n- `recycle_at_time` - schedule a pool to recycle at a specific time, d.hh:mm:ss, d optional\n- `private_memory` - specifies the amount of private memory (in kilobytes) after which you want the pool to recycle\n- `virtual_memory` - specifies the amount of virtual memory (in kilobytes) after which you want the pool to recycle\n\n#### Failure Items\n\n- `load_balancer_capabilities` - Specifies behavior when a worker process cannot be started, such as when the request queue is full or an application pool is in rapid-fail protection. - default is :HttpLevel - optional\n- `orphan_worker_process` - Specifies whether to assign a worker process to an orphan state instead of terminating it when an application pool fails. - default is false - optional\n- `orphan_action_exe` - Specifies an executable to run when the WWW service orphans a worker process (if the orphanWorkerProcess attribute is set to true). You can use the orphanActionParams attribute to send parameters to the executable. - optional\n- `orphan_action_params` - Indicates command-line parameters for the executable named by the orphanActionExe attribute. To specify the process ID of the orphaned process, use %1%. - optional\n- `rapid_fail_protection` - Setting to true instructs the WWW service to remove from service all applications that are in an application pool - default is true - optional\n- `rapid_fail_protection_interval` - Specifies the number of minutes before the failure count for a process is reset. - default is '00:05:00' - optional\n- `rapid_fail_protection_max_crashes` - Specifies the maximum number of failures that are allowed within the number of minutes specified by the rapidFailProtectionInterval attribute. - default is 5 - optional\n- `auto_shutdown_exe` - Specifies an executable to run when the WWW service shuts down an application pool. - optional\n- `auto_shutdown_params` - Specifies command-line parameters for the executable that is specified in the autoShutdownExe attribute. - optional\n\n##### CPU Items\n\n- `cpu_action` - Configures the action that IIS takes when a worker process exceeds its configured CPU limit. The action attribute is configured on a per-application pool basis. - Available options [:NoAction, :KillW3wp, :Throttle, :ThrottleUnderLoad] - default is :NoAction - optional\n- `cpu_limit` - Configures the maximum percentage of CPU time (in 1/1000ths of one percent) that the worker processes in an application pool are allowed to consume over a period of time as indicated by the resetInterval attribute. If the limit set by the limit attribute is exceeded, an event is written to the event log and an optional set of events can be triggered. These optional events are determined by the action attribute. - default is 0 - optional\n- `cpu_reset_interval` - Specifies the reset period (in minutes) for CPU monitoring and throttling limits on an application pool. When the number of minutes elapsed since the last process accounting reset equals the number specified by this property, IIS resets the CPU timers for both the logging and limit intervals. - default is '00:05:00' - optional\n- `cpu_smp_affinitized` - Specifies whether a particular worker process assigned to an application pool should also be assigned to a given CPU. - default is false - optional\n- `smp_processor_affinity_mask` - Specifies the hexadecimal processor mask for multi-processor computers, which indicates to which CPU the worker processes in an application pool should be bound. Before this property takes effect, the smpAffinitized attribute must be set to true for the application pool. - default is 4294967295 - optional\n- `smp_processor_affinity_mask_2` - Specifies the high-order DWORD hexadecimal processor mask for 64-bit multi-processor computers, which indicates to which CPU the worker processes in an application pool should be bound. Before this property takes effect, the smpAffinitized attribute must be set to true for the application pool. - default is 4294967295 - optional\n\n#### Example\n\n```ruby\n# creates a new app pool\niis_pool 'myAppPool_v1_1' do\n runtime_version \"2.0\"\n pipeline_mode :Classic\n action :add\nend\n```\n\n### iis_app\n\nCreates an application in IIS.\n\n#### Actions\n\n- `:add` - add a new application pool\n- `:delete` - delete an existing application pool\n- `:config` - configures an existing application pool\n\n#### Properties\n\n- `site_name` - name attribute. The name of the site to add this app to\n- `path` -The virtual path for this application\n- `application_pool` - The pool this application belongs to\n- `physical_path` - The physical path where this app resides.\n- `enabled_protocols` - The enabled protocols that this app provides (http, https, net.pipe, net.tcp, etc)\n\n#### Example\n\n```ruby\n# creates a new app\niis_app 'myApp' do\n path '/v1_1'\n application_pool 'myAppPool_v1_1'\n physical_path \"#{node['iis']['docroot']}/testfu/v1_1\"\n enabled_protocols 'http,net.pipe'\n action :add\nend\n```\n\n### iis_vdir\n\nAllows easy management of IIS virtual directories (i.e. vdirs).\n\n#### Actions\n\n- :add: - add a new virtual directory\n- :delete: - delete an existing virtual directory\n- :config: - configure a virtual directory\n\n#### Attribute Parameters\n\n- `application_name`: name attribute. This is the name of the website or site + application you are adding it to.\n- `path`: The virtual directory path on the site.\n- `physical_path`: The physical path of the virtual directory on the disk.\n- `username`: (optional) The username required to logon to the physical_path. If set to \"\" will clear username and password.\n- `password`: (optional) The password required to logon to the physical_path\n- `logon_method`: (optional, default: :ClearText) The method used to logon (:Interactive, :Batch, :Network, :ClearText). For more information on these types, see \"LogonUser Function\", Read more at [MSDN](http://msdn2.microsoft.com/en-us/library/aa378184.aspx)\n- `allow_sub_dir_config`: (optional, default: 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.\n\n#### Examples\n\n```ruby\n# add a virtual directory to default application\niis_vdir 'Default Web Site/' do\n action :add\n path '/Content/Test'\n physical_path 'C:\\wwwroot\\shared\\test'\nend\n```\n\n```ruby\n# add a virtual directory to an application under a site\niis_vdir 'Default Web Site/my application' do\n action :add\n path '/Content/Test'\n physical_path 'C:\\wwwroot\\shared\\test'\nend\n```\n\n```ruby\n# adds a virtual directory to default application which points to a smb share. (Remember to escape the \"\\\"'s)\niis_vdir 'Default Web Site/' do\n action :add\n path '/Content/Test'\n physical_path '\\\\\\\\sharename\\\\sharefolder\\\\1'\nend\n```\n\n```ruby\n# configure a virtual directory to have a username and password\niis_vdir 'Default Web Site/' do\n action :config\n path '/Content/Test'\n username 'domain\\myspecialuser'\n password 'myspecialpassword'\nend\n```\n\n```ruby\n# delete a virtual directory from the default application\niis_vdir 'Default Web Site/' do\n action :delete\n path '/Content/Test'\nend\n```\n\n### iis_section\n\nAllows for the locking/unlocking of sections ([listed here](http://www.iis.net/configreference) or via the command `appcmd list config \\\"\\\" /config:* /xml`)\n\nThis is valuable to allow the `web.config` of an individual application/website control it's own settings.\n\n#### Actions\n\n- `:lock`: - locks the `section` passed\n- `:unlock`: - unlocks the `section` passed\n\n#### Attribute Parameters\n\n- `section`: The name of the section to lock.\n- `site`: The name of the site you want to lock or unlock a section for.\n- `application_path`: The path to the application you want to lock or unlock a section for.\n- `returns`: The result of the `shell_out` command.\n- \n\n#### Examples\n\n```ruby\n# Sets the IIS global windows authentication to be locked globally\niis_section 'locks global configuration of windows auth' do\n section 'system.webServer/security/authentication/windowsAuthentication'\n action :lock\nend\n```\n\n```ruby\n# Sets the IIS global Basic authentication to be locked globally\niis_section 'locks global configuration of Basic auth' do\n section 'system.webServer/security/authentication/basicAuthentication'\n action :lock\nend\n```\n\n```ruby\n# Sets the IIS global windows authentication to be unlocked globally\niis_section 'unlocked web.config globally for windows auth' do\n action :unlock\n section 'system.webServer/security/authentication/windowsAuthentication'\nend\n```\n\n```ruby\n# Sets the IIS global Basic authentication to be unlocked globally\niis_section 'unlocked web.config globally for Basic auth' do\n action :unlock\n section 'system.webServer/security/authentication/basicAuthentication'\nend\n```\n\n```ruby\n# Sets the static content section for default web site and root to unlocked\niis_section 'unlock staticContent of default web site' do\n section 'system.webServer/staticContent'\n site 'Default Web Site'\n action :unlock\nend\n```\n\n```ruby\n# Sets the static content section for test_app under default website and root to be unlocked\niis_section 'unlock staticContent of default web site' do\n section 'system.webServer/staticContent'\n site 'Default Web Site'\n application_path '/test_app'\n action :unlock\nend\n```\n\n### iis_module\n\nManages modules globally or on a per site basis.\n\n#### Actions\n\n- `:add` - add a new module\n- `:delete` - delete a module\n- `:install` - install a native module from the filesystem (.dll)\n- `:uninstall` - uninstall a native module\n\n#### Attribute Parameters\n\n- `module_name` - The name of the module to add or delete\n- `type` - The type of module\n- `precondition` - precondition for module\n- `application` - The application or site to add the module to\n- `add` - Whether the module you install has to be globally added\n- `image` - Location of the DLL of the module to install\n\n#### Example\n\n```ruby\n# Adds a module called \"My 3rd Party Module\" to mySite/\niis_module \"My 3rd Party Module\" do\n application \"mySite/\"\n precondition \"bitness64\"\n action :add\nend\n```\n\n```ruby\n# Adds a module called \"MyModule\" to all IIS sites on the server\niis_module \"MyModule\"\n```\n\n## Usage\n\n### default recipe\n\nInstalls and configures IIS 7.0/7.5/8.0 using the default configuration.\n\n### mod_* recipes\n\nThis 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.\n\n- `mod_aspnet` - installs ASP.NET runtime components\n- `mod_aspnet45` - installs ASP.NET 4.5 runtime components\n- `mod_auth_basic` - installs Basic Authentication support\n- `mod_auth_windows` - installs Windows Authentication (authenticate clients by using NTLM or Kerberos) support\n- `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.\n- `mod_compress_static` - installs static content compression support\n- `mod_iis6_metabase_compat` - installs IIS 6 Metabase Compatibility component.\n- `mod_isapi` - installs ISAPI (Internet Server Application Programming Interface) extension and filter support.\n- `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\n- `mod_management` - installs Web server Management Console which supports management of local and remote Web servers\n- `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.\n- `mod_tracing` - installs support for tracing ASP.NET applications and failed requests.\n\nNote: 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.\n\n## Alternative Cookbooks\n\n- [Powershell based IIS Cookbook (Pre-DSC)](https://github.com/ebsco/iisposh)\n- DSC Based- [CWebAdministration](https://github.com/PowerShellOrg/cWebAdministration) / [XWebadministration](https://github.com/PowerShell/xWebAdministration) Powershell Module(s)\n\n## License and Author\n\n- Author:: Seth Chisamore ([schisamo@chef.io](mailto:schisamo@chef.io))\n- Author:: Julian Dunn ([jdunn@chef.io](mailto:jdunn@chef.io))\n- Author:: Justin Schuhmann ([jmschu02@gmail.com](mailto:jmschu02@gmail.com))\n\n```text\nCopyright 2011-2016, Chef Software, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```\n","maintainer":"Chef Software, Inc.","maintainer_email":"cookbooks@chef.io","license":"Apache-2.0","platforms":{"windows":">= 0.0.0"},"dependencies":{"windows":">= 2.0"},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{},"source_url":"https://github.com/chef-cookbooks/iis","issues_url":"https://github.com/chef-cookbooks/iis/issues","chef_version":">= 12.5","ohai_version":{}} \ No newline at end of file diff --git a/cookbooks/iis/providers/app.rb b/cookbooks/iis/providers/app.rb deleted file mode 100644 index ca2f5d8..0000000 --- a/cookbooks/iis/providers/app.rb +++ /dev/null @@ -1,144 +0,0 @@ -# -# Author:: Kendrick Martin (kendrick.martin@webtrends.com) -# Contributor:: Adam Wayne (awayne@waynedigital.com) -# Cookbook:: iis -# Provider:: app -# -# Copyright:: 2011-2016, Webtrends Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -require 'chef/mixin/shell_out' -require 'rexml/document' - -include Chef::Mixin::ShellOut -include REXML -include Opscode::IIS::Helper -include Opscode::IIS::Processors - -action :add do - if !@current_resource.exists - cmd = "#{appcmd(node)} add app /site.name:\"#{new_resource.site_name}\"" - cmd << " /path:\"#{new_resource.path}\"" - cmd << " /applicationPool:\"#{new_resource.application_pool}\"" if new_resource.application_pool - cmd << " /physicalPath:\"#{windows_cleanpath(new_resource.physical_path)}\"" if new_resource.physical_path - cmd << " /enabledProtocols:\"#{new_resource.enabled_protocols}\"" if new_resource.enabled_protocols - cmd << ' /commit:\"MACHINE/WEBROOT/APPHOST\"' - Chef::Log.debug(cmd) - shell_out!(cmd) - new_resource.updated_by_last_action(true) - Chef::Log.info('App created') - else - Chef::Log.debug("#{new_resource} app already exists - nothing to do") - end -end - -action :config do - @was_updated = false - cmd_current_values = "#{appcmd(node)} list app \"#{site_identifier}\" /config:* /xml" - Chef::Log.debug(cmd_current_values) - cmd_current_values = shell_out(cmd_current_values) - if cmd_current_values.stderr.empty? - xml = cmd_current_values.stdout - doc = Document.new(xml) - is_new_path = new_or_empty_value?(doc.root, 'APP/application/@path', new_resource.path.to_s) - is_new_application_pool = new_or_empty_value?(doc.root, 'APP/application/@applicationPool', new_resource.application_pool.to_s) - is_new_enabled_protocols = new_or_empty_value?(doc.root, 'APP/application/@enabledProtocols', new_resource.enabled_protocols.to_s) - is_new_physical_path = new_or_empty_value?(doc.root, 'APP/application/virtualDirectory/@physicalPath', new_resource.physical_path.to_s) - - # only get the beginning of the command if there is something that changeds - cmd = "#{appcmd(node)} set app \"#{site_identifier}\"" if (new_resource.path && is_new_path) || - (new_resource.application_pool && is_new_application_pool) || - (new_resource.enabled_protocols && is_new_enabled_protocols) - # adds path to the cmd - cmd << " /path:\"#{new_resource.path}\"" if new_resource.path && is_new_path - # adds applicationPool to the cmd - cmd << " /applicationPool:\"#{new_resource.application_pool}\"" if new_resource.application_pool && is_new_application_pool - # adds enabledProtocols to the cmd - cmd << " /enabledProtocols:\"#{new_resource.enabled_protocols}\"" if new_resource.enabled_protocols && is_new_enabled_protocols - Chef::Log.debug(cmd) - - if cmd.nil? - Chef::Log.debug("#{new_resource} application - nothing to do") - else - shell_out!(cmd) - @was_updated = true - end - - if (new_resource.path && is_new_path) || - (new_resource.application_pool && is_new_application_pool) || - (new_resource.enabled_protocols && is_new_enabled_protocols) - @was_updated = true - end - - if new_resource.physical_path && is_new_physical_path - @was_updated = true - cmd = "#{appcmd(node)} set vdir /vdir.name:\"#{vdir_identifier}\"" - cmd << " /physicalPath:\"#{windows_cleanpath(new_resource.physical_path)}\"" - Chef::Log.debug(cmd) - shell_out!(cmd) - end - if @was_updated - new_resource.updated_by_last_action(true) - Chef::Log.info("#{new_resource} configured application") - else - Chef::Log.debug("#{new_resource} application - nothing to do") - end - else - log "Failed to run iis_app action :config, #{cmd_current_values.stderr}" do - level :warn - end - end -end - -action :delete do - if @current_resource.exists - shell_out!("#{appcmd(node)} delete app \"#{site_identifier}\"") - new_resource.updated_by_last_action(true) - Chef::Log.info("#{new_resource} deleted") - else - Chef::Log.debug("#{new_resource} app does not exist - nothing to do") - end -end - -def load_current_resource - @current_resource = Chef::Resource::IisApp.new(new_resource.name) - @current_resource.site_name(new_resource.site_name) - @current_resource.path(new_resource.path) - @current_resource.application_pool(new_resource.application_pool) - cmd = shell_out("#{appcmd(node)} list app") - Chef::Log.debug("#{new_resource} list app command output: #{cmd.stdout}") - regex = /^APP\s\"#{new_resource.site_name}#{new_resource.path}\"/ - Chef::Log.debug('Running regex') - if cmd.stderr.empty? - result = cmd.stdout.match(regex) - Chef::Log.debug("#{new_resource} current_resource match output:#{result}") - @current_resource.exists = result - else - log "Failed to run iis_app action :load_current_resource, #{cmd_current_values.stderr}" do - level :warn - end - end -end - -private - -def site_identifier - "#{new_resource.site_name}#{new_resource.path}" -end - -# Ensure VDIR identifier has a trailing slash -def vdir_identifier - site_identifier.end_with?('/') ? site_identifier : site_identifier + '/' -end diff --git a/cookbooks/iis/providers/config.rb b/cookbooks/iis/providers/config.rb deleted file mode 100644 index 8f4bd34..0000000 --- a/cookbooks/iis/providers/config.rb +++ /dev/null @@ -1,51 +0,0 @@ -# -# Author:: Kendrick Martin (kendrick.martin@webtrends.com) -# Contributor:: David Dvorak (david.dvorak@webtrends.com) -# Cookbook:: iis -# Resource:: config -# -# Copyright:: 2011-2016, Webtrends Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -require 'chef/mixin/shell_out' - -include Chef::Mixin::ShellOut -include Opscode::IIS::Helper -include Opscode::IIS::Processors - -# :config deprecated, use :set instead -action :config do - Chef::Log.warn <<-eos - Use of action `:config` in resource `iis_config` is now deprecated and will be removed in a future release (v4.2.0). - `:set` should be used instead. - eos - new_resource.updated_by_last_action(true) if config -end - -action :set do - new_resource.updated_by_last_action(true) if config -end - -action :clear do - new_resource.updated_by_last_action(true) if config(:clear) -end - -def config(action = :set) - cmd = "#{appcmd(node)} #{action} config #{new_resource.cfg_cmd}" - Chef::Log.debug(cmd) - shell_out!(cmd, returns: new_resource.returns) - Chef::Log.info('IIS Config command run') - new_resource.updated_by_last_action(true) -end diff --git a/cookbooks/iis/providers/module.rb b/cookbooks/iis/providers/module.rb deleted file mode 100644 index 1ab764d..0000000 --- a/cookbooks/iis/providers/module.rb +++ /dev/null @@ -1,123 +0,0 @@ -# -# Author:: Jon DeCamp () -# Cookbook:: iis -# Provider:: site -# -# Copyright:: 2013-2016, Nordstrom, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -require 'chef/mixin/shell_out' -include Chef::Mixin::ShellOut -include Opscode::IIS::Helper -include Opscode::IIS::Processors - -# Support whyrun -def whyrun_supported? - true -end - -# appcmd syntax for adding modules -# appcmd add module /name:string /type:string /preCondition:string -action :add do - if !@current_resource.exists - converge_by("add IIS module #{new_resource.module_name}") do - cmd = "#{appcmd(node)} add module /module.name:\"#{new_resource.module_name}\"" - - if new_resource.application - cmd << " /app.name:\"#{new_resource.application}\"" - end - - cmd << " /type:\"#{new_resource.type}\"" if new_resource.type - - if new_resource.precondition - cmd << " /preCondition:\"#{new_resource.precondition}\"" - end - - shell_out!(cmd, returns: [0, 42]) - - Chef::Log.info("#{new_resource} added module '#{new_resource.module_name}'") - end - else - Chef::Log.debug("#{new_resource} module already exists - nothing to do") - end -end - -action :delete do - if @current_resource.exists - converge_by("delete IIS module #{new_resource.module_name}") do - cmd = "#{appcmd(node)} delete module /module.name:\"#{new_resource.module_name}\"" - if new_resource.application - cmd << " /app.name:\"#{new_resource.application}\"" - end - - shell_out!(cmd, returns: [0, 42]) - end - - Chef::Log.info("#{new_resource} deleted") - else - Chef::Log.debug("#{new_resource} module does not exist - nothing to do") - end -end - -# appcmd syntax for installing native modules -# appcmd install module /name:string /add:string(true|false) /image:string -action :install do - if !@current_resource.exists - converge_by("install IIS module #{new_resource.module_name}") do - cmd = "#{appcmd(node)} install module /name:\"#{new_resource.module_name}\"" - cmd << " /add:\"#{new_resource.add}\"" unless new_resource.add.nil? - cmd << " /image:\"#{new_resource.image}\"" if new_resource.image - cmd << " /preCondition:\"#{new_resource.precondition}\"" if new_resource.precondition - - shell_out!(cmd, returns: [0, 42]) - - Chef::Log.info("#{new_resource} installed module '#{new_resource.module_name}'") - end - else - Chef::Log.debug("#{new_resource} module already exists - nothing to do") - end -end - -# appcmd syntax for uninstalling native modules -# appcmd uninstall module -action :uninstall do - if @current_resource.exists - converge_by("uninstall IIS module #{new_resource.module_name}") do - cmd = "#{appcmd(node)} uninstall module \"#{new_resource.module_name}\"" - - shell_out!(cmd, returns: [0, 42]) - end - - Chef::Log.info("#{new_resource} uninstalled module '#{new_resource.module_name}'") - else - Chef::Log.debug("#{new_resource} module does not exists - nothing to do") - end -end - -def load_current_resource - @current_resource = Chef::Resource::IisModule.new(new_resource.name) - @current_resource.module_name(new_resource.module_name) - cmd = if new_resource.application - shell_out("#{appcmd(node)} list module /module.name:\"#{new_resource.module_name}\" /app.name:\"#{new_resource.application}\"") - else - shell_out("#{appcmd(node)} list module /module.name:\"#{new_resource.module_name}\"") - end - - # 'MODULE "Module Name" ( type:module.type, preCondition:condition )' - # 'MODULE "Module Name" ( native, preCondition:condition )' - - Chef::Log.debug("#{new_resource} list module command output: #{cmd.stdout}") - @current_resource.exists = !cmd.stdout.empty? -end diff --git a/cookbooks/iis/providers/pool.rb b/cookbooks/iis/providers/pool.rb deleted file mode 100644 index 6f7e996..0000000 --- a/cookbooks/iis/providers/pool.rb +++ /dev/null @@ -1,329 +0,0 @@ -# -# Author:: Kendrick Martin (kendrick.martin@webtrends.com) -# Contributor:: David Dvorak (david.dvorak@webtrends.com) -# Cookbook:: iis -# Provider:: pool -# -# Copyright:: 2011-2016, Webtrends Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -require 'chef/mixin/shell_out' -require 'rexml/document' - -include Chef::Mixin::ShellOut -include REXML -include Opscode::IIS::Helper -include Opscode::IIS::Processors - -action :add do - if !@current_resource.exists - cmd = "#{appcmd(node)} add apppool /name:\"#{new_resource.pool_name}\"" - if new_resource.no_managed_code - cmd << ' /managedRuntimeVersion:' - elsif new_resource.runtime_version - cmd << " /managedRuntimeVersion:v#{new_resource.runtime_version}" - end - cmd << " /managedPipelineMode:#{new_resource.pipeline_mode.capitalize}" if new_resource.pipeline_mode - cmd << ' /commit:\"MACHINE/WEBROOT/APPHOST\"' - Chef::Log.debug(cmd) - shell_out!(cmd) - configure - new_resource.updated_by_last_action(true) - Chef::Log.info('App pool created') - else - Chef::Log.debug("#{new_resource} pool already exists - nothing to do") - end -end - -action :config do - new_resource.updated_by_last_action(true) if configure -end - -action :delete do - if @current_resource.exists - shell_out!("#{appcmd(node)} delete apppool \"#{site_identifier}\"") - new_resource.updated_by_last_action(true) - Chef::Log.info("#{new_resource} deleted") - else - Chef::Log.debug("#{new_resource} pool does not exist - nothing to do") - end -end - -action :start do - if !@current_resource.running - shell_out!("#{appcmd(node)} start apppool \"#{site_identifier}\"") - new_resource.updated_by_last_action(true) - Chef::Log.info("#{new_resource} started") - else - Chef::Log.debug("#{new_resource} already running - nothing to do") - end -end - -action :stop do - if @current_resource.running - shell_out!("#{appcmd(node)} stop apppool \"#{site_identifier}\"") - new_resource.updated_by_last_action(true) - Chef::Log.info("#{new_resource} stopped") - else - Chef::Log.debug("#{new_resource} already stopped - nothing to do") - end -end - -action :restart do - shell_out!("#{appcmd(node)} stop APPPOOL \"#{site_identifier}\"") - sleep 2 - shell_out!("#{appcmd(node)} start APPPOOL \"#{site_identifier}\"") - new_resource.updated_by_last_action(true) - Chef::Log.info("#{new_resource} restarted") -end - -action :recycle do - shell_out!("#{appcmd(node)} recycle APPPOOL \"#{site_identifier}\"") - new_resource.updated_by_last_action(true) - Chef::Log.info("#{new_resource} recycled") -end - -def load_current_resource - @current_resource = Chef::Resource::IisPool.new(new_resource.name) - @current_resource.pool_name(new_resource.pool_name) - cmd = shell_out("#{appcmd(node)} list apppool") - # APPPOOL "DefaultAppPool" (MgdVersion:v2.0,MgdMode:Integrated,state:Started) - Chef::Log.debug("#{new_resource} list apppool command output: #{cmd.stdout}") - if cmd.stderr.empty? - result = cmd.stdout.gsub(/\r\n?/, "\n") # ensure we have no carriage returns - result = result.match(/^APPPOOL\s\"(#{new_resource.pool_name})\"\s\(MgdVersion:(.*),MgdMode:(.*),state:(.*)\)$/i) - Chef::Log.debug("#{new_resource} current_resource match output: #{result}") - if result - @current_resource.exists = true - @current_resource.running = result[4] =~ /Started/ ? true : false - else - @current_resource.exists = false - @current_resource.running = false - end - else - log "Failed to run iis_pool action :load_current_resource, #{cmd.stderr}" do - level :warn - end - end -end - -private - -def site_identifier - new_resource.pool_name -end - -def configure - @was_updated = false - cmd_current_values = "#{appcmd(node)} list apppool \"#{new_resource.pool_name}\" /config:* /xml" - Chef::Log.debug(cmd_current_values) - cmd_current_values = shell_out(cmd_current_values) - if cmd_current_values.stderr.empty? - xml = cmd_current_values.stdout - doc = Document.new(xml) - - # root items - is_new_managed_runtime_version = - if new_resource.no_managed_code - new_value?(doc.root, 'APPPOOL/@RuntimeVersion', '') - else - new_value?(doc.root, 'APPPOOL/@RuntimeVersion', "v#{new_resource.runtime_version}") - end - is_new_pipeline_mode = new_value?(doc.root, 'APPPOOL/@PipelineMode', new_resource.pipeline_mode) - - # add items - if iis_version >= 7.0 - is_new_auto_start = new_value?(doc.root, 'APPPOOL/add/@autoStart', new_resource.auto_start.to_s) - end - - if iis_version > 7.0 - is_new_start_mode = new_value?(doc.root, 'APPPOOL/add/@startMode', new_resource.start_mode.to_s) - end - - is_new_queue_length = new_value?(doc.root, 'APPPOOL/add/@queueLength', new_resource.queue_length.to_s) - is_new_enable_32_bit_app_on_win_64 = new_value?(doc.root, 'APPPOOL/add/@enable32BitAppOnWin64', new_resource.thirty_two_bit.to_s) - - # processModel items - is_new_max_processes = new_or_empty_value?(doc.root, 'APPPOOL/add/processModel/@maxProcesses', new_resource.max_proc.to_s) - is_new_load_user_profile = new_value?(doc.root, 'APPPOOL/add/processModel/@loadUserProfile', new_resource.load_user_profile.to_s) - if iis_version > 7.0 - is_new_identity_type = new_value?(doc.root, 'APPPOOL/add/processModel/@identityType', new_resource.pool_identity.to_s) - end - is_new_user_name = new_or_empty_value?(doc.root, 'APPPOOL/add/processModel/@userName', new_resource.pool_username.to_s) - is_new_password = new_or_empty_value?(doc.root, 'APPPOOL/add/processModel/@password', new_resource.pool_password.to_s) - if iis_version > 7.0 - is_new_logon_type = new_value?(doc.root, 'APPPOOL/add/processModel/@logonType', new_resource.logon_type.to_s) - end - is_new_manual_group_membership = new_value?(doc.root, 'APPPOOL/add/processModel/@manualGroupMembership', new_resource.manual_group_membership.to_s) - is_new_idle_timeout = new_value?(doc.root, 'APPPOOL/add/processModel/@idleTimeout', new_resource.idle_timeout.to_s) - if iis_version >= 8.5 - is_new_idle_timeout_action = new_value?(doc.root, 'APPPOOL/add/processModel/@idleTimeoutAction', new_resource.idle_timeout_action) - end - is_new_shutdown_time_limit = new_value?(doc.root, 'APPPOOL/add/processModel/@shutdownTimeLimit', new_resource.shutdown_time_limit.to_s) - is_new_startup_time_limit = new_value?(doc.root, 'APPPOOL/add/processModel/@startupTimeLimit', new_resource.startup_time_limit.to_s) - is_new_pinging_enabled = new_value?(doc.root, 'APPPOOL/add/processModel/@pingingEnabled', new_resource.pinging_enabled.to_s) - is_new_ping_interval = new_value?(doc.root, 'APPPOOL/add/processModel/@pingInterval', new_resource.ping_interval.to_s) - is_new_ping_response_time = new_value?(doc.root, 'APPPOOL/add/processModel/@pingResponseTime', new_resource.ping_response_time.to_s) - - # failure items - is_new_load_balancer_capabilities = new_value?(doc.root, 'APPPOOL/add/failure/@loadBalancerCapabilities', new_resource.load_balancer_capabilities.to_s) - is_new_orphan_worker_process = new_value?(doc.root, 'APPPOOL/add/failure/@orphanWorkerProcess', new_resource.orphan_worker_process.to_s) - is_new_orphan_action_exe = new_or_empty_value?(doc.root, 'APPPOOL/add/failure/@orphanActionExe', new_resource.orphan_action_exe.to_s) - is_new_orphan_action_params = new_or_empty_value?(doc.root, 'APPPOOL/add/failure/@orphanActionParams', new_resource.orphan_action_params.to_s) - is_new_rapid_fail_protection = new_value?(doc.root, 'APPPOOL/add/failure/@rapidFailProtection', new_resource.rapid_fail_protection.to_s) - is_new_rapid_fail_protection_interval = new_value?(doc.root, 'APPPOOL/add/failure/@rapidFailProtectionInterval', new_resource.rapid_fail_protection_interval.to_s) - is_new_rapid_fail_protection_max_crashes = new_value?(doc.root, 'APPPOOL/add/failure/@rapidFailProtectionMaxCrashes', new_resource.rapid_fail_protection_max_crashes.to_s) - is_new_auto_shutdown_exe = new_or_empty_value?(doc.root, 'APPPOOL/add/failure/@autoShutdownExe', new_resource.auto_shutdown_exe.to_s) - is_new_auto_shutdown_params = new_or_empty_value?(doc.root, 'APPPOOL/add/failure/@autoShutdownParams', new_resource.auto_shutdown_params.to_s) - - # recycling items - is_new_disallow_overlapping_rotation = new_value?(doc.root, 'APPPOOL/add/recycling/@disallowOverlappingRotation', new_resource.disallow_overlapping_rotation.to_s) - is_new_disallow_rotation_on_config_change = new_value?(doc.root, 'APPPOOL/add/recycling/@disallowRotationOnConfigChange', new_resource.disallow_rotation_on_config_change.to_s) - is_new_recycle_after_time = new_or_empty_value?(doc.root, 'APPPOOL/add/recycling/periodicRestart/@time', new_resource.recycle_after_time.to_s) - is_new_recycle_at_time = new_or_empty_value?(doc.root, "APPPOOL/add/recycling/periodicRestart/schedule/add[@value='#{new_resource.recycle_at_time}']/@value", new_resource.recycle_at_time.to_s) - is_new_private_memory = new_or_empty_value?(doc.root, 'APPPOOL/add/recycling/periodicRestart/@privateMemory', new_resource.private_mem.to_s) - is_new_virtual_memory = new_or_empty_value?(doc.root, 'APPPOOL/add/recycling/periodicRestart/@memory', new_resource.virtual_mem.to_s) - is_new_log_event_on_recycle = new_or_empty_value?(doc.root, 'APPPOOL/add/recycling/@logEventOnRecycle', new_resource.log_event_on_recycle.to_s) - - # cpu items - is_new_cpu_action = new_value?(doc.root, 'APPPOOL/add/cpu/@action', new_resource.cpu_action.to_s) - is_new_cpu_limit = new_value?(doc.root, 'APPPOOL/add/cpu/@limit', new_resource.cpu_limit.to_s) - is_new_cpu_smp_affinitized = new_value?(doc.root, 'APPPOOL/add/cpu/@smpAffinitized', new_resource.cpu_smp_affinitized.to_s) - is_new_cpu_reset_interval = new_value?(doc.root, 'APPPOOL/add/cpu/@resetInterval', new_resource.cpu_reset_interval.to_s) - is_new_smp_processor_affinity_mask = new_value?(doc.root, 'APPPOOL/add/cpu/@smpProcessorAffinityMask', new_resource.smp_processor_affinity_mask.floor) - is_new_smp_processor_affinity_mask_2 = new_value?(doc.root, 'APPPOOL/add/cpu/@smpProcessorAffinityMask2', new_resource.smp_processor_affinity_mask_2.floor) - - # Application Pool Config - @cmd = "#{appcmd(node)} set config /section:applicationPools" - - # root items - if iis_version >= 7.0 - configure_application_pool(is_new_auto_start, "autoStart:#{new_resource.auto_start}") - end - - if iis_version >= 7.5 - configure_application_pool(is_new_start_mode, "startMode:#{new_resource.start_mode}") - end - - if new_resource.no_managed_code - configure_application_pool(is_new_managed_runtime_version, 'managedRuntimeVersion:') - else - configure_application_pool(new_resource.runtime_version && is_new_managed_runtime_version, "managedRuntimeVersion:v#{new_resource.runtime_version}") - end - configure_application_pool(new_resource.pipeline_mode && is_new_pipeline_mode, "managedPipelineMode:#{new_resource.pipeline_mode}") - configure_application_pool(is_new_enable_32_bit_app_on_win_64, "enable32BitAppOnWin64:#{new_resource.thirty_two_bit}") - configure_application_pool(new_resource.queue_length && is_new_queue_length, "queueLength:#{new_resource.queue_length}") - - # processModel items - configure_application_pool(new_resource.max_proc && is_new_max_processes, "processModel.maxProcesses:#{new_resource.max_proc}") - configure_application_pool(is_new_load_user_profile, "processModel.loadUserProfile:#{new_resource.load_user_profile}") - configure_application_pool(is_new_logon_type, "processModel.logonType:#{new_resource.logon_type}") - configure_application_pool(is_new_manual_group_membership, "processModel.manualGroupMembership:#{new_resource.manual_group_membership}") - configure_application_pool(is_new_idle_timeout, "processModel.idleTimeout:#{new_resource.idle_timeout}") - if iis_version >= 8.5 - configure_application_pool(is_new_idle_timeout_action, "processModel.idleTimeoutAction:#{new_resource.idle_timeout_action}") - end - configure_application_pool(is_new_shutdown_time_limit, "processModel.shutdownTimeLimit:#{new_resource.shutdown_time_limit}") - configure_application_pool(is_new_startup_time_limit, "processModel.startupTimeLimit:#{new_resource.startup_time_limit}") - configure_application_pool(is_new_pinging_enabled, "processModel.pingingEnabled:#{new_resource.pinging_enabled}") - configure_application_pool(is_new_ping_interval, "processModel.pingInterval:#{new_resource.ping_interval}") - configure_application_pool(is_new_ping_response_time, "processModel.pingResponseTime:#{new_resource.ping_response_time}") - - node_array = XPath.match(doc.root, 'APPPOOL/add/recycling/periodicRestart/schedule/add') - should_clear_apppool_schedules = ((new_resource.recycle_at_time && is_new_recycle_at_time) && !node_array.empty?) || (new_resource.recycle_schedule_clear && !node_array.empty?) - - # recycling items - ## Special case this collection removal for now. - if should_clear_apppool_schedules - @was_updated = true - is_new_recycle_at_time = true - clear_pool_schedule_cmd = "#{appcmd(node)} set config /section:applicationPools \"/-[name='#{new_resource.pool_name}'].recycling.periodicRestart.schedule\"" - Chef::Log.debug(clear_pool_schedule_cmd) - shell_out!(clear_pool_schedule_cmd) - end - - configure_application_pool(new_resource.recycle_after_time && is_new_recycle_after_time, "recycling.periodicRestart.time:#{new_resource.recycle_after_time}") - configure_application_pool(new_resource.recycle_at_time && is_new_recycle_at_time, "recycling.periodicRestart.schedule.[value='#{new_resource.recycle_at_time}']", '+') - configure_application_pool(new_resource.log_event_on_recycle && is_new_log_event_on_recycle, "recycling.logEventOnRecycle:#{new_resource.log_event_on_recycle}") - configure_application_pool(new_resource.private_mem && is_new_private_memory, "recycling.periodicRestart.privateMemory:#{new_resource.private_mem}") - configure_application_pool(new_resource.virtual_mem && is_new_virtual_memory, "recycling.periodicRestart.memory:#{new_resource.virtual_mem}") - configure_application_pool(is_new_disallow_rotation_on_config_change, "recycling.disallowRotationOnConfigChange:#{new_resource.disallow_rotation_on_config_change}") - configure_application_pool(is_new_disallow_overlapping_rotation, "recycling.disallowOverlappingRotation:#{new_resource.disallow_overlapping_rotation}") - - # failure items - configure_application_pool(is_new_load_balancer_capabilities, "failure.loadBalancerCapabilities:#{new_resource.load_balancer_capabilities}") - configure_application_pool(is_new_orphan_worker_process, "failure.orphanWorkerProcess:#{new_resource.orphan_worker_process}") - configure_application_pool(new_resource.orphan_action_exe && is_new_orphan_action_exe, "failure.orphanActionExe:#{new_resource.orphan_action_exe}") - configure_application_pool(new_resource.orphan_action_params && is_new_orphan_action_params, "failure.orphanActionParams:#{new_resource.orphan_action_params}") - configure_application_pool(is_new_rapid_fail_protection, "failure.rapidFailProtection:#{new_resource.rapid_fail_protection}") - configure_application_pool(is_new_rapid_fail_protection_interval, "failure.rapidFailProtectionInterval:#{new_resource.rapid_fail_protection_interval}") - configure_application_pool(is_new_rapid_fail_protection_max_crashes, "failure.rapidFailProtectionMaxCrashes:#{new_resource.rapid_fail_protection_max_crashes}") - configure_application_pool(new_resource.auto_shutdown_exe && is_new_auto_shutdown_exe, "failure.autoShutdownExe:#{new_resource.auto_shutdown_exe}") - configure_application_pool(new_resource.auto_shutdown_params && is_new_auto_shutdown_params, "failure.autoShutdownParams:#{new_resource.auto_shutdown_params}") - - # cpu items - configure_application_pool(is_new_cpu_action, "cpu.action:#{new_resource.cpu_action}") - configure_application_pool(is_new_cpu_limit, "cpu.limit:#{new_resource.cpu_limit}") - configure_application_pool(is_new_cpu_reset_interval, "cpu.resetInterval:#{new_resource.cpu_reset_interval}") - configure_application_pool(is_new_cpu_smp_affinitized, "cpu.smpAffinitized:#{new_resource.cpu_smp_affinitized}") - configure_application_pool(is_new_smp_processor_affinity_mask, "cpu.smpProcessorAffinityMask:#{new_resource.smp_processor_affinity_mask.floor}") - configure_application_pool(is_new_smp_processor_affinity_mask_2, "cpu.smpProcessorAffinityMask2:#{new_resource.smp_processor_affinity_mask_2.floor}") - - if @cmd != "#{appcmd(node)} set config /section:applicationPools" - Chef::Log.debug(@cmd) - shell_out!(@cmd) - end - - # Application Pool Identity Settings - if (new_resource.pool_username && new_resource.pool_username != '') && (is_new_user_name || is_new_password) - @was_updated = true - cmd = "#{appcmd(node)} set config /section:applicationPools" - cmd << " \"/[name='#{new_resource.pool_name}'].processModel.identityType:SpecificUser\"" - cmd << " \"/[name='#{new_resource.pool_name}'].processModel.userName:#{new_resource.pool_username}\"" - cmd << " \"/[name='#{new_resource.pool_name}'].processModel.password:#{new_resource.pool_password}\"" if new_resource.pool_password && new_resource.pool_password != '' && is_new_password - Chef::Log.debug(cmd) - shell_out!(cmd) - elsif (new_resource.pool_username.nil? || new_resource.pool_username == '') && - (new_resource.pool_password.nil? || new_resource.pool_username == '') && - (is_new_identity_type && new_resource.pool_identity != 'SpecificUser') - @was_updated = true - cmd = "#{appcmd(node)} set config /section:applicationPools" - cmd << " \"/[name='#{new_resource.pool_name}'].processModel.identityType:#{new_resource.pool_identity}\"" - Chef::Log.debug(cmd) - shell_out!(cmd) - end - - if @was_updated - Chef::Log.info("#{new_resource} configured application pool") - else - Chef::Log.debug("#{new_resource} application pool - nothing to do") - end - else - log "Failed to run iis_pool action :config, #{cmd_current_values.stderr}" do - level :warn - end - end - - @was_updated -end - -private - -def configure_application_pool(condition, config, add_remove = '') - return unless condition - - @was_updated = true - @cmd << " \"/#{add_remove}[name='#{new_resource.pool_name}'].#{config}\"" -end diff --git a/cookbooks/iis/providers/root.rb b/cookbooks/iis/providers/root.rb deleted file mode 100644 index 3358017..0000000 --- a/cookbooks/iis/providers/root.rb +++ /dev/null @@ -1,68 +0,0 @@ -# -# Author:: Justin Schuhmann () -# Cookbook:: iis -# Provider:: root -# -# Copyright:: 2016, Justin Schuhmann -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -include Opscode::IIS::Helper -include Opscode::IIS::Processors - -action :add do - @was_updated = false - - @was_updated = default_documents(new_resource.add_default_documents, new_resource.default_documents_enabled, true, false) | @was_updated - @was_updated = mime_maps(new_resource.add_mime_maps, true, false) | @was_updated - - if @was_updated - new_resource.updated_by_last_action(true) - else - Chef::Log.debug("#{new_resource} - nothing to do") - end -end - -action :delete do - @was_updated = false - - @was_updated = default_documents(new_resource.delete_default_documents, new_resource.default_documents_enabled, false) | @was_updated - @was_updated = mime_maps(new_resource.delete_mime_maps, false) | @was_updated - - if @was_updated - new_resource.updated_by_last_action(true) - else - Chef::Log.debug("#{new_resource} - nothing to do") - end -end - -action :config do - @was_updated = false - - @was_updated = default_documents(new_resource.default_documents, new_resource.default_documents_enabled) | @was_updated - @was_updated = mime_maps(new_resource.mime_maps) | @was_updated - - if @was_updated - new_resource.updated_by_last_action(true) - else - Chef::Log.debug("#{new_resource} - nothing to do") - end -end - -def load_current_resource - @current_resource = Chef::Resource::IisRoot.new(new_resource.name) - @current_resource.default_documents(new_resource.default_documents) - @current_resource.default_documents_enabled(new_resource.default_documents_enabled) - @current_resource.mime_maps(new_resource.mime_maps) -end diff --git a/cookbooks/iis/providers/section.rb b/cookbooks/iis/providers/section.rb deleted file mode 100644 index 173ac28..0000000 --- a/cookbooks/iis/providers/section.rb +++ /dev/null @@ -1,72 +0,0 @@ -# -# Author:: Justin Schuhmann -# Cookbook:: iis -# Resource:: lock -# -# Copyright:: 2016, Justin Schuhmann -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -require 'chef/mixin/shell_out' -require 'rexml/document' - -include Chef::Mixin::ShellOut -include REXML -include Opscode::IIS::Helper -include Opscode::IIS::Processors - -action :lock do - @current_resource.exists = new_value?(doc.root, 'CONFIG/@overrideMode', 'Deny') - - if @current_resource.exists - cmd = "#{appcmd(node)} lock config -section:\"#{new_resource.section}\" -commit:apphost" - Chef::Log.debug(cmd) - shell_out!(cmd, returns: new_resource.returns) - new_resource.updated_by_last_action(true) - Chef::Log.info('IIS Config command run') - else - Chef::Log.debug("#{new_resource.section} already locked - nothing to do") - end -end - -action :unlock do - @current_resource.exists = new_value?(doc.root, 'CONFIG/@overrideMode', 'Allow') - - if @current_resource.exists - cmd = "#{appcmd(node)} unlock config -section:\"#{new_resource.section}\" -commit:apphost" - Chef::Log.debug(cmd) - shell_out!(cmd, returns: new_resource.returns) - new_resource.updated_by_last_action(true) - Chef::Log.info('IIS Config command run') - else - Chef::Log.debug("#{new_resource.section} already unlocked - nothing to do") - end -end - -def load_current_resource - @current_resource = Chef::Resource::IisSection.new(new_resource.section) - @current_resource.section(new_resource.section) -end - -def doc - cmd_current_values = "#{appcmd(node)} list config -section:#{new_resource.section} /config:* /xml" - Chef::Log.debug(cmd_current_values) - cmd_current_values = shell_out(cmd_current_values) - if cmd_current_values.stderr.empty? - xml = cmd_current_values.stdout - return Document.new(xml) - end - - cmd_current_values.error! -end diff --git a/cookbooks/iis/providers/site.rb b/cookbooks/iis/providers/site.rb deleted file mode 100644 index 5c8ebbf..0000000 --- a/cookbooks/iis/providers/site.rb +++ /dev/null @@ -1,226 +0,0 @@ -# -# Author:: Seth Chisamore () -# Cookbook:: iis -# Provider:: site -# -# Copyright:: 2011-2016, Chef Software, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -require 'chef/mixin/shell_out' -require 'rexml/document' - -include Chef::Mixin::ShellOut -include REXML -include Opscode::IIS::Helper -include Opscode::IIS::Processors - -action :add do - if !@current_resource.exists - cmd = "#{appcmd(node)} add site /name:\"#{new_resource.site_name}\"" - cmd << " /id:#{new_resource.site_id}" if new_resource.site_id - cmd << " /physicalPath:\"#{windows_cleanpath(new_resource.path)}\"" if new_resource.path - if new_resource.bindings - cmd << " /bindings:\"#{new_resource.bindings}\"" - else - cmd << " /bindings:#{new_resource.protocol}/*" - cmd << ":#{new_resource.port}:" if new_resource.port - cmd << new_resource.host_header if new_resource.host_header - end - - # support for additional options -logDir, -limits, -ftpServer, etc... - cmd << " #{new_resource.options}" if new_resource.options - shell_out!(cmd, returns: [0, 42]) - - configure - - if new_resource.application_pool - shell_out!("#{appcmd(node)} set site /site.name:\"#{new_resource.site_name}\" /[path='/'].applicationPool:\"#{new_resource.application_pool}\"", returns: [0, 42]) - end - new_resource.updated_by_last_action(true) - Chef::Log.info("#{new_resource} added new site '#{new_resource.site_name}'") - else - Chef::Log.debug("#{new_resource} site already exists - nothing to do") - end -end - -action :config do - new_resource.updated_by_last_action(true) if configure -end - -action :delete do - if @current_resource.exists - Chef::Log.info("#{appcmd(node)} stop site /site.name:\"#{new_resource.site_name}\"") - shell_out!("#{appcmd(node)} delete site /site.name:\"#{new_resource.site_name}\"", returns: [0, 42]) - new_resource.updated_by_last_action(true) - Chef::Log.info("#{new_resource} deleted") - else - Chef::Log.debug("#{new_resource} site does not exist - nothing to do") - end -end - -action :start do - if !@current_resource.running - shell_out!("#{appcmd(node)} start site /site.name:\"#{new_resource.site_name}\"", returns: [0, 42]) - new_resource.updated_by_last_action(true) - Chef::Log.info("#{new_resource} started") - else - Chef::Log.debug("#{new_resource} already running - nothing to do") - end -end - -action :stop do - if @current_resource.running - Chef::Log.info("#{appcmd(node)} stop site /site.name:\"#{new_resource.site_name}\"") - shell_out!("#{appcmd(node)} stop site /site.name:\"#{new_resource.site_name}\"", returns: [0, 42]) - new_resource.updated_by_last_action(true) - Chef::Log.info("#{new_resource} stopped") - else - Chef::Log.debug("#{new_resource} already stopped - nothing to do") - end -end - -action :restart do - shell_out!("#{appcmd(node)} stop site /site.name:\"#{new_resource.site_name}\"", returns: [0, 42]) - sleep 2 - shell_out!("#{appcmd(node)} start site /site.name:\"#{new_resource.site_name}\"", returns: [0, 42]) - new_resource.updated_by_last_action(true) - Chef::Log.info("#{new_resource} restarted") -end - -def load_current_resource - @current_resource = Chef::Resource::IisSite.new(new_resource.name) - @current_resource.site_name(new_resource.site_name) - cmd = shell_out("#{appcmd(node)} list site") - Chef::Log.debug(appcmd(node)) - # 'SITE "Default Web Site" (id:1,bindings:http/*:80:,state:Started)' - Chef::Log.debug("#{new_resource} list site command output: #{cmd.stdout}") - if cmd.stderr.empty? - result = cmd.stdout.gsub(/\r\n?/, "\n") # ensure we have no carriage returns - result = result.match(/^SITE\s\"(#{new_resource.site_name})\"\s\(id:(.*),bindings:(.*),state:(.*)\)$/i) - Chef::Log.debug("#{new_resource} current_resource match output: #{result}") - if result - @current_resource.site_id(result[2].to_i) - @current_resource.exists = true - @current_resource.bindings(result[3]) - @current_resource.running = result[4] =~ /Started/ ? true : false - else - @current_resource.exists = false - @current_resource.running = false - end - else - log "Failed to run iis_site action :config, #{cmd.stderr}" do - level :warn - end - end -end - -private - -def configure - @was_updated = false - cmd_current_values = "#{appcmd(node)} list site \"#{new_resource.site_name}\" /config:* /xml" - Chef::Log.debug(cmd_current_values) - cmd_current_values = shell_out(cmd_current_values) - if cmd_current_values.stderr.empty? - xml = cmd_current_values.stdout - doc = Document.new(xml) - is_new_bindings = new_value?(doc.root, 'SITE/@bindings', new_resource.bindings.to_s) - is_new_physical_path = new_or_empty_value?(doc.root, 'SITE/site/application/virtualDirectory/@physicalPath', new_resource.path.to_s) - is_new_port_host_provided = !"#{XPath.first(doc.root, 'SITE/@bindings')},".include?("#{new_resource.protocol}/*:#{new_resource.port}:#{new_resource.host_header},") - is_new_site_id = new_value?(doc.root, 'SITE/site/@id', new_resource.site_id.to_s) - is_new_log_directory = new_or_empty_value?(doc.root, 'SITE/site/logFile/@directory', new_resource.log_directory.to_s) - is_new_log_period = new_or_empty_value?(doc.root, 'SITE/site/logFile/@period', new_resource.log_period.to_s) - is_new_log_trunc = new_or_empty_value?(doc.root, 'SITE/site/logFile/@truncateSize', new_resource.log_truncsize.to_s) - is_new_application_pool = new_value?(doc.root, 'SITE/site/application/@applicationPool', new_resource.application_pool) - - if new_resource.bindings && is_new_bindings - @was_updated = true - cmd = "#{appcmd(node)} set site /site.name:\"#{new_resource.site_name}\"" - cmd << " /bindings:\"#{new_resource.bindings}\"" - shell_out!(cmd) - new_resource.updated_by_last_action(true) - elsif ((new_resource.port || new_resource.host_header || new_resource.protocol) && is_new_port_host_provided) && !new_resource.bindings - @was_updated = true - cmd = "#{appcmd(node)} set site \"#{new_resource.site_name}\"" - cmd << " /bindings:#{new_resource.protocol}/*:#{new_resource.port}:#{new_resource.host_header}" - Chef::Log.debug(cmd) - shell_out!(cmd) - new_resource.updated_by_last_action(true) - end - - if new_resource.application_pool && is_new_application_pool - @was_updated = true - cmd = "#{appcmd(node)} set app \"#{new_resource.site_name}/\" /applicationPool:\"#{new_resource.application_pool}\"" - Chef::Log.debug(cmd) - shell_out!(cmd, returns: [0, 42]) - end - - if new_resource.path && is_new_physical_path - @was_updated = true - cmd = "#{appcmd(node)} set vdir \"#{new_resource.site_name}/\"" - cmd << " /physicalPath:\"#{windows_cleanpath(new_resource.path)}\"" - Chef::Log.debug(cmd) - shell_out!(cmd) - end - - if new_resource.site_id && is_new_site_id - @was_updated = true - cmd = "#{appcmd(node)} set site \"#{new_resource.site_name}\"" - cmd << " /id:#{new_resource.site_id}" - Chef::Log.debug(cmd) - shell_out!(cmd) - new_resource.updated_by_last_action(true) - end - - if new_resource.log_directory && is_new_log_directory - @was_updated = true - cmd = "#{appcmd(node)} set site \"#{new_resource.site_name}\"" - cmd << " /logFile.directory:#{windows_cleanpath(new_resource.log_directory)}" - Chef::Log.debug(cmd) - shell_out!(cmd) - new_resource.updated_by_last_action(true) - end - - if new_resource.log_period && is_new_log_period - @was_updated = true - cmd = "#{appcmd(node)} set site \"#{new_resource.site_name}\"" - cmd << " /logFile.period:#{new_resource.log_period}" - Chef::Log.debug(cmd) - shell_out!(cmd) - new_resource.updated_by_last_action(true) - end - - if new_resource.log_truncsize && is_new_log_trunc - @was_updated = true - cmd = "#{appcmd(node)} set site \"#{new_resource.site_name}\"" - cmd << " /logFile.truncateSize:#{new_resource.log_truncsize}" - Chef::Log.debug(cmd) - shell_out!(cmd) - new_resource.updated_by_last_action(true) - end - - if @was_updated - Chef::Log.info("#{new_resource} configured site '#{new_resource.site_name}'") - else - Chef::Log.debug("#{new_resource} site - nothing to do") - end - else - log "Failed to run iis_site action :config, #{cmd_current_values.stderr}" do - level :warn - end - end - - @was_updated -end diff --git a/cookbooks/iis/providers/vdir.rb b/cookbooks/iis/providers/vdir.rb deleted file mode 100644 index bcb24f1..0000000 --- a/cookbooks/iis/providers/vdir.rb +++ /dev/null @@ -1,155 +0,0 @@ -# -# Author:: Justin Schuhmann () -# Cookbook:: iis -# Provider:: site -# -# Copyright:: 2016, Justin Schuhmann -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -require 'chef/mixin/shell_out' -require 'rexml/document' - -include Chef::Mixin::ShellOut -include REXML -include Opscode::IIS::Helper -include Opscode::IIS::Processors - -action :add do - if !@current_resource.exists - cmd = "#{appcmd(node)} add vdir /app.name:\"#{new_resource.application_name}\"" - cmd << " /path:\"#{new_resource.path}\"" - cmd << " /physicalPath:\"#{windows_cleanpath(new_resource.physical_path)}\"" - cmd << " /userName:\"#{new_resource.username}\"" if new_resource.username - cmd << " /password:\"#{new_resource.password}\"" if new_resource.password - cmd << " /logonMethod:#{new_resource.logon_method}" if new_resource.logon_method - cmd << " /allowSubDirConfig:#{new_resource.allow_sub_dir_config}" if new_resource.allow_sub_dir_config - cmd << ' /commit:\"MACHINE/WEBROOT/APPHOST\"' - - Chef::Log.info(cmd) - shell_out!(cmd, returns: [0, 42, 183]) - new_resource.updated_by_last_action(true) - Chef::Log.info("#{new_resource} added new virtual directory to application: '#{new_resource.application_name}'") - else - Chef::Log.debug("#{new_resource} virtual directory already exists - nothing to do") - end -end - -action :config do - @was_updated = false - cmd_current_values = "#{appcmd(node)} list vdir \"#{application_identifier}\" /config:* /xml" - Chef::Log.debug(cmd_current_values) - cmd_current_values = shell_out!(cmd_current_values) - if cmd_current_values.stderr.empty? - xml = cmd_current_values.stdout - doc = Document.new(xml) - is_new_physical_path = new_or_empty_value?(doc.root, 'VDIR/@physicalPath', new_resource.physical_path.to_s) - is_new_user_name = new_or_empty_value?(doc.root, 'VDIR/virtualDirectory/@userName', new_resource.username.to_s) - is_new_password = new_or_empty_value?(doc.root, 'VDIR/virtualDirectory/@password', new_resource.password.to_s) - is_new_logon_method = new_or_empty_value?(doc.root, 'VDIR/virtualDirectory/@logonMethod', new_resource.logon_method.to_s) - is_new_allow_sub_dir_config = new_or_empty_value?(doc.root, 'VDIR/virtualDirectory/@allowSubDirConfig', new_resource.allow_sub_dir_config.to_s) - - if new_resource.physical_path && is_new_physical_path - @was_updated = true - cmd = "#{appcmd(node)} set vdir \"#{application_identifier}\" /physicalPath:\"#{new_resource.physical_path}\"" - Chef::Log.debug(cmd) - shell_out!(cmd) - end - - if new_resource.username && is_new_user_name - @was_updated = true - cmd = "#{appcmd(node)} set vdir \"#{application_identifier}\" /userName:\"#{new_resource.username}\"" - Chef::Log.debug(cmd) - shell_out!(cmd) - end - - if new_resource.password && is_new_password - @was_updated = true - cmd = "#{appcmd(node)} set vdir \"#{application_identifier}\" /password:\"#{new_resource.password}\"" - Chef::Log.debug(cmd) - shell_out!(cmd) - end - - if new_resource.logon_method && is_new_logon_method - @was_updated = true - cmd = "#{appcmd(node)} set vdir \"#{application_identifier}\" /logonMethod:#{new_resource.logon_method}" - Chef::Log.debug(cmd) - shell_out!(cmd) - end - - if new_resource.allow_sub_dir_config && is_new_allow_sub_dir_config - @was_updated = true - cmd = "#{appcmd(node)} set vdir \"#{application_identifier}\" /allowSubDirConfig:#{new_resource.allow_sub_dir_config}" - Chef::Log.debug(cmd) - shell_out!(cmd) - end - - if @was_updated - new_resource.updated_by_last_action(true) - Chef::Log.info("#{new_resource} configured virtual directory to application: '#{new_resource.application_name}'") - else - Chef::Log.debug("#{new_resource} virtual directory - nothing to do") - end - else - log "Failed to run iis_vdir action :config, #{cmd_current_values.stderr}" do - level :warn - end - end -end - -action :delete do - if @current_resource.exists - shell_out!("#{appcmd(node)} delete vdir \"#{application_identifier}\"", returns: [0, 42]) - new_resource.updated_by_last_action(true) - Chef::Log.info("#{new_resource} deleted") - else - Chef::Log.debug("#{new_resource} virtual directory does not exist - nothing to do") - end -end - -def load_current_resource - @current_resource = Chef::Resource::IisVdir.new(new_resource.name) - @current_resource.application_name(application_name_check) - @current_resource.path(new_resource.path) - @current_resource.physical_path(new_resource.physical_path) - cmd = shell_out("#{appcmd(node)} list vdir \"#{application_identifier}\"") - Chef::Log.debug("#{new_resource} list vdir command output: #{cmd.stdout}") - - if cmd.stderr.empty? - # VDIR "Testfu Site/Content/Test" - result = cmd.stdout.match(/^VDIR\s\"#{Regexp.escape(application_identifier)}\"/) - Chef::Log.debug("#{new_resource} current_resource match output: #{result}") - @current_resource.exists = result - else - log "Failed to run iis_vdir action :load_current_resource, #{cmd_current_values.stderr}" do - level :warn - end - end -end - -private - -def application_identifier - new_resource.application_name.chomp('/') + new_resource.path -end - -def application_name_check - if !new_resource.application_name.include?('/') && !new_resource.application_name.end_with?('/') - new_resource.application_name("#{new_resource.application_name}/") - elsif new_resource.application_name.chomp('/').include?('/') && new_resource.application_name.end_with?('/') - new_resource.application_name(new_resource.application_name.chomp('/')) - else - new_resource.application_name - end -end diff --git a/cookbooks/iis/resources/app.rb b/cookbooks/iis/resources/app.rb index 4382662..59f9201 100644 --- a/cookbooks/iis/resources/app.rb +++ b/cookbooks/iis/resources/app.rb @@ -1,9 +1,8 @@ # -# Author:: Kendrick Martin (kendrick.martin@webtrends.com>) # Cookbook:: iis # Resource:: app # -# Copyright:: 2011-2016, Webtrends Inc. +# Copyright:: 2011-2017, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -18,15 +17,130 @@ # limitations under the License. # -actions :add, :delete, :config +require 'rexml/document' + +include REXML +include Opscode::IIS::Helper + +property :site_name, String, name_property: true +property :path, String, default: '/' +property :application_pool, String +property :physical_path, String +property :enabled_protocols, String + default_action :add -attribute :site_name, kind_of: String, name_attribute: true -attribute :path, kind_of: String, default: '/' -attribute :application_pool, kind_of: String -attribute :physical_path, kind_of: String -attribute :enabled_protocols, kind_of: String -attribute :default_documents, kind_of: Array, default: [] -attribute :mime_maps, kind_of: Array, default: [] +load_current_value do |desired| + site_name desired.site_name + # Sanitize physical path + desired.physical_path = windows_cleanpath(desired.physical_path) if desired.physical_path + cmd = shell_out("#{appcmd(node)} list app \"#{desired.site_name}#{desired.path}\"") + Chef::Log.debug("#{appcmd(node)} list app command output: #{cmd.stdout}") + if cmd.stderr.empty? + Chef::Log.debug('Running regex') + regex = /^APP\s\"#{desired.site_name}#{desired.path}\"/ + result = cmd.stdout.match(regex) + Chef::Log.debug("#{desired} current_resource match output: #{result}") + if !result.nil? + cmd_current_values = "#{appcmd(node)} list app \"#{desired.site_name}#{desired.path}\" /config:* /xml" + Chef::Log.debug(cmd_current_values) + cmd_current_values = shell_out(cmd_current_values) + if cmd_current_values.stderr.empty? + xml = cmd_current_values.stdout + doc = Document.new(xml) + path value doc.root, 'APP/application/@path' + application_pool value doc.root, 'APP/application/@applicationPool' + enabled_protocols value doc.root, 'APP/application/@enabledProtocols' + physical_path windows_cleanpath(value(doc.root, 'APP/application/virtualDirectory/@physicalPath')) + end + else + path '' + end + else + Chef::Log.warn "Failed to run iis_app action :load_current_resource, #{cmd_current_values.stderr}" + end +end -attr_accessor :exists, :running +action :add do + if exists + Chef::Log.debug("#{new_resource.inspect} app already exists - nothing to do") + else + converge_by "Creating the Application - \"#{new_resource}\"" do + cmd = "#{appcmd(node)} add app /site.name:\"#{new_resource.site_name}\"" + cmd << " /path:\"#{new_resource.path}\"" + cmd << " /applicationPool:\"#{new_resource.application_pool}\"" if new_resource.application_pool + cmd << " /physicalPath:\"#{new_resource.physical_path}\"" if new_resource.physical_path + cmd << " /enabledProtocols:\"#{new_resource.enabled_protocols}\"" if new_resource.enabled_protocols + cmd << ' /commit:\"MACHINE/WEBROOT/APPHOST\"' + Chef::Log.debug(cmd) + shell_out!(cmd) + end + end +end + +action :config do + if exists + # only get the beginning of the command if there is something that changes + cmd = cmd_set_app + converge_if_changed :path do + # adds path to the cmd + cmd << " /path:\"#{new_resource.path}\"" if new_resource.path + end + converge_if_changed :application_pool do + # adds applicationPool to the cmd + cmd << " /applicationPool:\"#{new_resource.application_pool}\"" if new_resource.application_pool + end + converge_if_changed :enabled_protocols do + # adds enabledProtocols to the cmd + cmd << " /enabledProtocols:\"#{new_resource.enabled_protocols}\"" if new_resource.enabled_protocols + end + Chef::Log.debug(cmd) + + if cmd == cmd_set_app + Chef::Log.debug("#{new_resource.inspect} application - nothing to do") + else + converge_by "Updating the Application - \"#{new_resource}\"" do + shell_out!(cmd) + end + end + + converge_if_changed :physical_path do + cmd = "#{appcmd(node)} set vdir /vdir.name:\"#{vdir_identifier}\"" + cmd << " /physicalPath:\"#{new_resource.physical_path}\"" + Chef::Log.debug(cmd) + shell_out!(cmd) + end + else + Chef::Log.debug("#{new_resource.inspect} app needs to be added - cannot configure non-existent items") + end +end + +action :delete do + if exists + converge_by "Deleting the Application - \"#{new_resource}\"" do + shell_out!("#{appcmd(node)} delete app \"#{site_identifier}\"") + Chef::Log.info("#{new_resource} deleted") + end + else + Chef::Log.debug("#{new_resource.inspect} app does not exist - nothing to do") + end +end + +action_class.class_eval do + def exists + !current_resource.path.empty? + end + + def cmd_set_app + "#{appcmd(node)} set app \"#{site_identifier}\"" + end + + def site_identifier + "#{new_resource.site_name}#{new_resource.path}" + end + + # Ensure VDIR identifier has a trailing slash + def vdir_identifier + site_identifier.end_with?('/') ? site_identifier : site_identifier + '/' + end +end diff --git a/cookbooks/iis/resources/config.rb b/cookbooks/iis/resources/config.rb index d7a3e65..40b76f4 100644 --- a/cookbooks/iis/resources/config.rb +++ b/cookbooks/iis/resources/config.rb @@ -1,9 +1,8 @@ # -# Author:: Kendrick Martin (kendrick.martin@webtrends.com) # Cookbook:: iis # Resource:: config # -# Copyright:: 2011-2016, Webtrends Inc. +# Copyright:: 2017, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -18,8 +17,28 @@ # limitations under the License. # -actions :config, :clear, :set +include Opscode::IIS::Helper +include Opscode::IIS::Processors + +property :cfg_cmd, String, name_attribute: true +property :returns, [Integer, Array], default: 0 + default_action :set -attribute :cfg_cmd, kind_of: String, name_attribute: true -attribute :returns, kind_of: [Integer, Array], default: 0 +action :set do + config +end + +action :clear do + config(:clear) +end + +action_class.class_eval do + def config(action = :set) + converge_by "Executing IIS Config #{action}" do + cmd = "#{appcmd(node)} #{action} config #{new_resource.cfg_cmd}" + Chef::Log.debug(cmd) + shell_out!(cmd, returns: new_resource.returns) + end + end +end diff --git a/cookbooks/iis/resources/module.rb b/cookbooks/iis/resources/module.rb index 2d5c5d5..8d97e04 100644 --- a/cookbooks/iis/resources/module.rb +++ b/cookbooks/iis/resources/module.rb @@ -1,9 +1,8 @@ # -# Author:: Jon DeCamp () # Cookbook:: iis # Resource:: module # -# Copyright:: 2012-2016, Nordstrom, Inc. +# Copyright:: 2017, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -18,14 +17,119 @@ # limitations under the License. # -actions :add, :delete, :install, :uninstall +include Opscode::IIS::Helper +include Opscode::IIS::Processors +include Opscode::IIS::SectionHelper + +property :module_name, String, name_property: true +property :type, String +property :add, [true, false], default: false +property :image, String +property :precondition, String +property :application, String +property :previous_lock, String + default_action :add -attribute :module_name, kind_of: String, name_attribute: true -attribute :type, kind_of: String, default: nil -attribute :add, kind_of: [FalseClass, TrueClass], default: nil -attribute :image, kind_of: String, default: nil -attribute :precondition, kind_of: String, default: nil -attribute :application, kind_of: String, default: nil +load_current_value do |desired| + module_name desired.module_name + application desired.application if desired.application + # Sanitize Image Path (file system path) + desired.image = windows_cleanpath(desired.image) if desired.image + cmd = "#{appcmd(node)} list module /module.name:\"#{desired.module_name}\"" + cmd << " /app.name:\"#{desired.application}\"" if desired.application -attr_accessor :exists + cmd_result = shell_out cmd + # 'MODULE "Module Name" ( type:module.type, preCondition:condition )' + # 'MODULE "Module Name" ( native, preCondition:condition )' + + Chef::Log.debug("#{desired.name} list module command output: #{cmd_result.stdout}") + unless cmd_result.stdout.empty? + previous_lock get_current_lock(node, 'system.webServer/modules', desired.application) + cmd = "#{appcmd(node)} list module /module.name:\"#{desired.module_name}\"" + cmd << " /app.name:\"#{desired.application}\"" if desired.application + cmd << ' /config:* /xml' + cmd_result = shell_out cmd + if cmd_result.stderr.empty? + xml = cmd_result.stdout + doc = Document.new(xml) + type value doc.root, 'MODULE/@type' + precondition value doc.root, 'MODULE/@preCondition' + end + end +end + +# appcmd syntax for adding modules +# appcmd add module /name:string /type:string /preCondition:string +action :add do + if exists + Chef::Log.debug("#{new_resource} module already exists - nothing to do") + else + converge_by("add IIS module #{new_resource.module_name}") do + unlock(node, 'system.webServer/modules', new_resource.application) + cmd = "#{appcmd(node)} add module /module.name:\"#{new_resource.module_name}\"" + cmd << " /app.name:\"#{new_resource.application}\"" if new_resource.application + cmd << " /type:\"#{new_resource.type}\"" if new_resource.type + cmd << " /preCondition:\"#{new_resource.precondition}\"" if new_resource.precondition + + shell_out!(cmd, returns: [0, 42]) + override_mode(node, current_resource.previous_lock, 'system.webServer/modules', new_resource.application) + end + end +end + +action :delete do + if exists + converge_by("delete IIS module #{new_resource.module_name}") do + unlock(node, 'system.webServer/modules', new_resource.application) + cmd = "#{appcmd(node)} delete module /module.name:\"#{new_resource.module_name}\"" + cmd << " /app.name:\"#{new_resource.application}\"" if new_resource.application + + shell_out!(cmd, returns: [0, 42]) + override_mode(node, current_resource.previous_lock, 'system.webServer/modules', new_resource.application) + end + else + Chef::Log.debug("#{new_resource} module does not exist - nothing to do") + end +end + +# appcmd syntax for installing native modules +# appcmd install module /name:string /add:string(true|false) /image:string +action :install do + if exists + Chef::Log.debug("#{new_resource} module already exists - nothing to do") + else + converge_by("install IIS module #{new_resource.module_name}") do + unlock(node, 'system.webServer/modules', new_resource.application) + cmd = "#{appcmd(node)} install module /name:\"#{new_resource.module_name}\"" + cmd << " /add:\"#{new_resource.add}\"" unless new_resource.add.nil? + cmd << " /image:\"#{new_resource.image}\"" if new_resource.image + cmd << " /preCondition:\"#{new_resource.precondition}\"" if new_resource.precondition + + shell_out!(cmd, returns: [0, 42]) + override_mode(node, current_resource.previous_lock, 'system.webServer/modules', new_resource.application) + end + end +end + +# appcmd syntax for uninstalling native modules +# appcmd uninstall module +action :uninstall do + if exists + converge_by("uninstall IIS module #{new_resource.module_name}") do + unlock(node, 'system.webServer/modules', new_resource.application) + cmd = "#{appcmd(node)} uninstall module \"#{new_resource.module_name}\"" + + shell_out!(cmd, returns: [0, 42]) + override_mode(node, current_resource.previous_lock, 'system.webServer/modules', new_resource.application) + end + else + Chef::Log.debug("#{new_resource} module does not exists - nothing to do") + end +end + +action_class.class_eval do + def exists + current_resource.type ? true : false + end +end diff --git a/cookbooks/iis/resources/pool.rb b/cookbooks/iis/resources/pool.rb index d2ed780..5f97a57 100644 --- a/cookbooks/iis/resources/pool.rb +++ b/cookbooks/iis/resources/pool.rb @@ -1,10 +1,8 @@ # -# Author:: Kendrick Martin (kendrick.martin@webtrends.com>) -# Contributor:: David Dvorak (david.dvorak@webtrends.com) # Cookbook:: iis # Resource:: pool # -# Copyright:: 2011-2016, Webtrends Inc. +# Copyright:: 2017, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -19,64 +17,435 @@ # limitations under the License. # -actions :add, :config, :delete, :start, :stop, :restart, :recycle -default_action :add +require 'rexml/document' + +include REXML +include Opscode::IIS::Helper +include Opscode::IIS::Processors # root -attribute :pool_name, kind_of: String, name_attribute: true -attribute :no_managed_code, kind_of: [TrueClass, FalseClass], default: false -attribute :pipeline_mode, kind_of: Symbol, equal_to: [:Integrated, :Classic] -attribute :runtime_version, kind_of: String +property :name, String, name_property: true +property :no_managed_code, [true, false], default: false +property :pipeline_mode, [Symbol, String], equal_to: [:Integrated, :Classic], coerce: proc { |v| v.to_sym } +property :runtime_version, String # add items -attribute :start_mode, kind_of: Symbol, equal_to: [:AlwaysRunning, :OnDemand], default: :OnDemand -attribute :auto_start, kind_of: [TrueClass, FalseClass], default: true -attribute :queue_length, kind_of: Integer, default: 1000 -attribute :thirty_two_bit, kind_of: [TrueClass, FalseClass], default: false +property :start_mode, [Symbol, String], equal_to: [:AlwaysRunning, :OnDemand], default: :OnDemand, coerce: proc { |v| v.to_sym } +property :auto_start, [true, false], default: true +property :queue_length, Integer, default: 1000, coerce: proc { |v| v.to_i } +property :thirty_two_bit, [true, false], default: false # processModel items -attribute :max_proc, kind_of: Integer -attribute :load_user_profile, kind_of: [TrueClass, FalseClass], default: false -attribute :pool_identity, kind_of: Symbol, equal_to: [:SpecificUser, :NetworkService, :LocalService, :LocalSystem, :ApplicationPoolIdentity], default: :ApplicationPoolIdentity -attribute :pool_username, kind_of: String -attribute :pool_password, kind_of: String -attribute :logon_type, kind_of: Symbol, equal_to: [:LogonBatch, :LogonService], default: :LogonBatch -attribute :manual_group_membership, kind_of: [TrueClass, FalseClass], default: false -attribute :idle_timeout, kind_of: String, default: '00:20:00' -attribute :idle_timeout_action, kind_of: Symbol, equal_to: [:Terminate, :Suspend], default: :Terminate -attribute :shutdown_time_limit, kind_of: String, default: '00:01:30' -attribute :startup_time_limit, kind_of: String, default: '00:01:30' -attribute :pinging_enabled, kind_of: [TrueClass, FalseClass], default: true -attribute :ping_interval, kind_of: String, default: '00:00:30' -attribute :ping_response_time, kind_of: String, default: '00:01:30' +property :max_processes, Integer, coerce: proc { |v| v.to_i } +property :load_user_profile, [true, false], default: false +property :identity_type, [Symbol, String], equal_to: [:SpecificUser, :NetworkService, :LocalService, :LocalSystem, :ApplicationPoolIdentity], default: :ApplicationPoolIdentity, coerce: proc { |v| v.to_sym } +property :username, String +property :password, String +property :logon_type, [Symbol, String], equal_to: [:LogonBatch, :LogonService], default: :LogonBatch, coerce: proc { |v| v.to_sym } +property :manual_group_membership, [true, false], default: false +property :idle_timeout, String, default: '00:20:00' +property :idle_timeout_action, [Symbol, String], equal_to: [:Terminate, :Suspend], default: :Terminate, coerce: proc { |v| v.to_sym } +property :shutdown_time_limit, String, default: '00:01:30' +property :startup_time_limit, String, default: '00:01:30' +property :pinging_enabled, [true, false], default: true +property :ping_interval, String, default: '00:00:30' +property :ping_response_time, String, default: '00:01:30' # recycling items -attribute :disallow_rotation_on_config_change, kind_of: [TrueClass, FalseClass], default: false -attribute :disallow_overlapping_rotation, kind_of: [TrueClass, FalseClass], default: false -attribute :recycle_schedule_clear, kind_of: [TrueClass, FalseClass], default: false -attribute :log_event_on_recycle, kind_of: String, default: node['iis']['recycle']['log_events'] -attribute :recycle_after_time, kind_of: String -attribute :recycle_at_time, kind_of: String -attribute :private_mem, kind_of: Integer -attribute :virtual_mem, kind_of: Integer +property :disallow_rotation_on_config_change, [true, false], default: false +property :disallow_overlapping_rotation, [true, false], default: false +property :recycle_schedule_clear, [true, false], default: false +property :log_event_on_recycle, String, default: node['iis']['recycle']['log_events'] +property :recycle_after_time, String +property :recycle_at_time, String +property :private_memory, Integer, coerce: proc { |v| v.to_i } +property :virtual_memory, Integer, coerce: proc { |v| v.to_i } # failure items -attribute :load_balancer_capabilities, kind_of: Symbol, equal_to: [:HttpLevel, :TcpLevel], default: :HttpLevel -attribute :orphan_worker_process, kind_of: [TrueClass, FalseClass], default: false -attribute :orphan_action_exe, kind_of: String -attribute :orphan_action_params, kind_of: String -attribute :rapid_fail_protection, kind_of: [TrueClass, FalseClass], default: true -attribute :rapid_fail_protection_interval, kind_of: String, default: '00:05:00' -attribute :rapid_fail_protection_max_crashes, kind_of: Integer, default: 5 -attribute :auto_shutdown_exe, kind_of: String -attribute :auto_shutdown_params, kind_of: String +property :load_balancer_capabilities, [Symbol, String], equal_to: [:HttpLevel, :TcpLevel], default: :HttpLevel, coerce: proc { |v| v.to_sym } +property :orphan_worker_process, [true, false], default: false +property :orphan_action_exe, String +property :orphan_action_params, String +property :rapid_fail_protection, [true, false], default: true +property :rapid_fail_protection_interval, String, default: '00:05:00' +property :rapid_fail_protection_max_crashes, Integer, default: 5, coerce: proc { |v| v.to_i } +property :auto_shutdown_exe, String +property :auto_shutdown_params, String # cpu items -attribute :cpu_action, kind_of: Symbol, equal_to: [:NoAction, :KillW3wp, :Throttle, :ThrottleUnderLoad], default: :NoAction -attribute :cpu_limit, kind_of: Integer, default: 0 -attribute :cpu_reset_interval, kind_of: String, default: '00:05:00' -attribute :cpu_smp_affinitized, kind_of: [TrueClass, FalseClass], default: false -attribute :smp_processor_affinity_mask, kind_of: Float, default: 4_294_967_295.0 -attribute :smp_processor_affinity_mask_2, kind_of: Float, default: 4_294_967_295.0 +property :cpu_action, [Symbol, String], equal_to: [:NoAction, :KillW3wp, :Throttle, :ThrottleUnderLoad], default: :NoAction, coerce: proc { |v| v.to_sym } +property :cpu_limit, Integer, default: 0, coerce: proc { |v| v.to_i } +property :cpu_reset_interval, String, default: '00:05:00' +property :cpu_smp_affinitized, [true, false], default: false +property :smp_processor_affinity_mask, Float, default: 4_294_967_295.0, coerce: proc { |v| v.to_f } +property :smp_processor_affinity_mask_2, Float, default: 4_294_967_295.0, coerce: proc { |v| v.to_f } -attr_accessor :exists, :running +# internally used for the state of the pool [Starting, Started, Stopping, Stopped, Unknown, Undefined value] +property :running, [true, false], desired_state: true + +default_action :add + +load_current_value do |desired| + name desired.name + cmd = shell_out("#{appcmd(node)} list apppool \"#{desired.name}\"") + # APPPOOL "DefaultAppPool" (MgdVersion:v2.0,MgdMode:Integrated,state:Started) + Chef::Log.debug("#{desired} list apppool command output: #{cmd.stdout}") + unless cmd.stderr.empty? + Chef::Log.warn "Failed to run iis_pool action :load_current_resource, #{cmd.stderr}" + return + end + + result = cmd.stdout.gsub(/\r\n?/, "\n") # ensure we have no carriage returns + result = result.match(/^APPPOOL\s\"(#{desired.name})\"\s\(MgdVersion:(.*),MgdMode:(.*),state:(.*)\)$/i) + Chef::Log.debug("#{desired} current_resource match output: #{result}") + unless result + running false + return + end + + running result[4] =~ /Started/ ? true : false + cmd_current_values = "#{appcmd(node)} list apppool \"#{desired.name}\" /config:* /xml" + Chef::Log.debug(cmd_current_values) + cmd_current_values = shell_out(cmd_current_values) + if cmd_current_values.stderr.empty? + xml = cmd_current_values.stdout + doc = Document.new(xml) + + # root items + runtime_version value(doc.root, 'APPPOOL/@RuntimeVersion').gsub(/^v/, '') + pipeline_mode value(doc.root, 'APPPOOL/@PipelineMode').to_sym + + # add items + auto_start bool(value(doc.root, 'APPPOOL/add/@autoStart')) if iis_version >= 7.0 + start_mode value(doc.root, 'APPPOOL/add/@startMode').to_sym if iis_version > 7.0 + queue_length value(doc.root, 'APPPOOL/add/@queueLength').to_i + thirty_two_bit bool(value(doc.root, 'APPPOOL/add/@enable32BitAppOnWin64')) + + # processModel items + max_processes value(doc.root, 'APPPOOL/add/processModel/@maxProcesses').to_i + load_user_profile bool(value(doc.root, 'APPPOOL/add/processModel/@loadUserProfile')) + identity_type value(doc.root, 'APPPOOL/add/processModel/@identityType').to_sym if iis_version > 7.0 + username value doc.root, 'APPPOOL/add/processModel/@userName' + unless username.nil? || desired.username.nil? + Chef::Log.info('username: ' + username + ' -> ' + desired.username) + end + password value doc.root, 'APPPOOL/add/processModel/@password' + logon_type value(doc.root, 'APPPOOL/add/processModel/@logonType').to_sym if iis_version > 7.0 + manual_group_membership bool(value(doc.root, 'APPPOOL/add/processModel/@manualGroupMembership')) + idle_timeout value doc.root, 'APPPOOL/add/processModel/@idleTimeout' + idle_timeout_action value(doc.root, 'APPPOOL/add/processModel/@idleTimeoutAction').to_sym if iis_version >= 8.5 + shutdown_time_limit value doc.root, 'APPPOOL/add/processModel/@shutdownTimeLimit' + startup_time_limit value doc.root, 'APPPOOL/add/processModel/@startupTimeLimit' + pinging_enabled bool(value(doc.root, 'APPPOOL/add/processModel/@pingingEnabled')) + ping_interval value doc.root, 'APPPOOL/add/processModel/@pingInterval' + ping_response_time value doc.root, 'APPPOOL/add/processModel/@pingResponseTime' + + # recycling items + disallow_overlapping_rotation bool(value(doc.root, 'APPPOOL/add/recycling/@disallowOverlappingRotation')) + disallow_rotation_on_config_change bool(value(doc.root, 'APPPOOL/add/recycling/@disallowRotationOnConfigChange')) + recycle_after_time value doc.root, 'APPPOOL/add/recycling/periodicRestart/@time' + recycle_at_time value doc.root, "APPPOOL/add/recycling/periodicRestart/schedule/add[@value='#{desired.recycle_at_time}']/@value" + private_memory value(doc.root, 'APPPOOL/add/recycling/periodicRestart/@privateMemory').to_i + virtual_memory value(doc.root, 'APPPOOL/add/recycling/periodicRestart/@memory').to_i + log_event_on_recycle value doc.root, 'APPPOOL/add/recycling/@logEventOnRecycle' + + # failure items + load_balancer_capabilities value(doc.root, 'APPPOOL/add/failure/@loadBalancerCapabilities').to_sym + orphan_worker_process bool(value(doc.root, 'APPPOOL/add/failure/@orphanWorkerProcess')) + orphan_action_exe value doc.root, 'APPPOOL/add/failure/@orphanActionExe' + orphan_action_params value doc.root, 'APPPOOL/add/failure/@orphanActionParams' + rapid_fail_protection bool(value(doc.root, 'APPPOOL/add/failure/@rapidFailProtection')) + rapid_fail_protection_interval value doc.root, 'APPPOOL/add/failure/@rapidFailProtectionInterval' + rapid_fail_protection_max_crashes value(doc.root, 'APPPOOL/add/failure/@rapidFailProtectionMaxCrashes').to_i + auto_shutdown_exe value doc.root, 'APPPOOL/add/failure/@autoShutdownExe' + auto_shutdown_params value doc.root, 'APPPOOL/add/failure/@autoShutdownParams' + + # cpu items + cpu_action value(doc.root, 'APPPOOL/add/cpu/@action').to_sym + cpu_limit value(doc.root, 'APPPOOL/add/cpu/@limit').to_i + cpu_smp_affinitized bool(value(doc.root, 'APPPOOL/add/cpu/@smpAffinitized')) + cpu_reset_interval value doc.root, 'APPPOOL/add/cpu/@resetInterval' + smp_processor_affinity_mask value(doc.root, 'APPPOOL/add/cpu/@smpProcessorAffinityMask').to_f + smp_processor_affinity_mask_2 value(doc.root, 'APPPOOL/add/cpu/@smpProcessorAffinityMask2').to_f + + @node_array = XPath.match(doc.root, 'APPPOOL/add/recycling/periodicRestart/schedule/add') + end +end + +action :add do + if exists + Chef::Log.debug("#{new_resource} pool already exists - nothing to do") + else + converge_by "Created Application Pool \"#{new_resource}\"" do + cmd = "#{appcmd(node)} add apppool /name:\"#{new_resource.name}\"" + if new_resource.no_managed_code + cmd << ' /managedRuntimeVersion:' + elsif new_resource.runtime_version + cmd << " /managedRuntimeVersion:v#{new_resource.runtime_version}" + end + cmd << " /managedPipelineMode:#{new_resource.pipeline_mode.capitalize}" if new_resource.pipeline_mode + cmd << ' /commit:\"MACHINE/WEBROOT/APPHOST\"' + Chef::Log.debug(cmd) + shell_out!(cmd) + configure + end + end +end + +action :config do + configure if exists +end + +action :delete do + if exists + converge_by "Deleted Application Pool \"#{new_resource}\"" do + shell_out!("#{appcmd(node)} delete apppool \"#{new_resource.name}\"") + end + else + Chef::Log.debug("#{new_resource} pool does not exist - nothing to do") + end +end + +action :start do + if exists && !current_resource.running + converge_by "Started Application Pool \"#{new_resource}\"" do + shell_out!("#{appcmd(node)} start apppool \"#{new_resource.name}\"") + end + else + Chef::Log.debug("#{new_resource} already running - nothing to do") + end +end + +action :stop do + if exists && current_resource.running + converge_by "Stopped Application Pool \"#{new_resource}\"" do + shell_out!("#{appcmd(node)} stop apppool \"#{new_resource.name}\"") + end + else + Chef::Log.debug("#{new_resource} already stopped - nothing to do") + end +end + +action :restart do + if exists + converge_by "Restarted Application Pool \"#{new_resource}\"" do + shell_out!("#{appcmd(node)} stop APPPOOL \"#{new_resource.name}\"") if current_resource.running + sleep 2 + shell_out!("#{appcmd(node)} start APPPOOL \"#{new_resource.name}\"") + end + end +end + +action :recycle do + if exists + converge_by "Recycled Application Pool \"#{new_resource}\"" do + shell_out!("#{appcmd(node)} recycle APPPOOL \"#{new_resource.name}\"") if current_resource.running + end + end +end + +action_class.class_eval do + def exists + current_resource.runtime_version ? true : false + end + + def configure + # Application Pool Config + cmd = "#{appcmd(node)} set config /section:applicationPools" + + # root items + if iis_version >= 7.0 + converge_if_changed :auto_start do + cmd << configure_application_pool("autoStart:#{new_resource.auto_start}") + end + end + + if iis_version >= 7.5 + converge_if_changed :start_mode do + cmd << configure_application_pool("startMode:#{new_resource.start_mode}") + end + end + + if new_resource.no_managed_code + converge_if_changed :runtime_version do + cmd << configure_application_pool('managedRuntimeVersion:') + end + else + converge_if_changed :runtime_version do + cmd << configure_application_pool("managedRuntimeVersion:v#{new_resource.runtime_version}") + end + end + + converge_if_changed :pipeline_mode do + cmd << configure_application_pool("managedPipelineMode:#{new_resource.pipeline_mode}") + end + converge_if_changed :thirty_two_bit do + cmd << configure_application_pool("enable32BitAppOnWin64:#{new_resource.thirty_two_bit}") + end + converge_if_changed :queue_length do + cmd << configure_application_pool("queueLength:#{new_resource.queue_length}") + end + + # processModel items + converge_if_changed :max_processes do + cmd << configure_application_pool("processModel.maxProcesses:#{new_resource.max_processes}") + end + converge_if_changed :load_user_profile do + cmd << configure_application_pool("processModel.loadUserProfile:#{new_resource.load_user_profile}") + end + converge_if_changed :logon_type do + cmd << configure_application_pool("processModel.logonType:#{new_resource.logon_type}") + end + converge_if_changed :manual_group_membership do + cmd << configure_application_pool("processModel.manualGroupMembership:#{new_resource.manual_group_membership}") + end + converge_if_changed :idle_timeout do + cmd << configure_application_pool("processModel.idleTimeout:#{new_resource.idle_timeout}") + end + if iis_version >= 8.5 + converge_if_changed :idle_timeout_action do + cmd << configure_application_pool("processModel.idleTimeoutAction:#{new_resource.idle_timeout_action}") + end + end + converge_if_changed :shutdown_time_limit do + cmd << configure_application_pool("processModel.shutdownTimeLimit:#{new_resource.shutdown_time_limit}") + end + converge_if_changed :startup_time_limit do + cmd << configure_application_pool("processModel.startupTimeLimit:#{new_resource.startup_time_limit}") + end + converge_if_changed :pinging_enabled do + cmd << configure_application_pool("processModel.pingingEnabled:#{new_resource.pinging_enabled}") + end + converge_if_changed :ping_interval do + cmd << configure_application_pool("processModel.pingInterval:#{new_resource.ping_interval}") + end + converge_if_changed :ping_response_time do + cmd << configure_application_pool("processModel.pingResponseTime:#{new_resource.ping_response_time}") + end + + should_clear_apppool_schedules = ((new_resource.recycle_at_time != current_resource.recycle_at_time) && !@node_array.nil? && !@node_array.empty?) || (new_resource.recycle_schedule_clear && !@node_array.nil? && !@node_array.empty?) + + # recycling items + ## Special case this collection removal for now. + # TODO: test if this is needed + # is_new_recycle_at_time = true + if !current_resource.runtime_version && should_clear_apppool_schedules + converge_by "Cleared Periodic Restart Schedule #{new_resource} - #{should_clear_apppool_schedules}" do + clear_pool_schedule_cmd = "#{appcmd(node)} set config /section:applicationPools \"/-[name='#{new_resource.name}'].recycling.periodicRestart.schedule\"" + Chef::Log.debug(clear_pool_schedule_cmd) + shell_out!(clear_pool_schedule_cmd) + end + end + + converge_if_changed :recycle_after_time do + cmd << configure_application_pool("recycling.periodicRestart.time:#{new_resource.recycle_after_time}") + end + converge_if_changed :recycle_at_time do + cmd << configure_application_pool("recycling.periodicRestart.schedule.[value='#{new_resource.recycle_at_time}']", '+') + end + converge_if_changed :log_event_on_recycle do + cmd << configure_application_pool("recycling.logEventOnRecycle:#{new_resource.log_event_on_recycle}") + end + converge_if_changed :private_memory do + cmd << configure_application_pool("recycling.periodicRestart.privateMemory:#{new_resource.private_memory}") + end + converge_if_changed :virtual_memory do + cmd << configure_application_pool("recycling.periodicRestart.memory:#{new_resource.virtual_memory}") + end + converge_if_changed :disallow_rotation_on_config_change do + cmd << configure_application_pool("recycling.disallowRotationOnConfigChange:#{new_resource.disallow_rotation_on_config_change}") + end + converge_if_changed :disallow_overlapping_rotation do + cmd << configure_application_pool("recycling.disallowOverlappingRotation:#{new_resource.disallow_overlapping_rotation}") + end + + # failure items + converge_if_changed :load_balancer_capabilities do + cmd << configure_application_pool("failure.loadBalancerCapabilities:#{new_resource.load_balancer_capabilities}") + end + converge_if_changed :orphan_worker_process do + cmd << configure_application_pool("failure.orphanWorkerProcess:#{new_resource.orphan_worker_process}") + end + converge_if_changed :orphan_action_exe do + cmd << configure_application_pool("failure.orphanActionExe:#{new_resource.orphan_action_exe}") + end + converge_if_changed :orphan_action_params do + cmd << configure_application_pool("failure.orphanActionParams:#{new_resource.orphan_action_params}") + end + converge_if_changed :rapid_fail_protection do + cmd << configure_application_pool("failure.rapidFailProtection:#{new_resource.rapid_fail_protection}") + end + converge_if_changed :rapid_fail_protection_interval do + cmd << configure_application_pool("failure.rapidFailProtectionInterval:#{new_resource.rapid_fail_protection_interval}") + end + converge_if_changed :rapid_fail_protection_max_crashes do + cmd << configure_application_pool("failure.rapidFailProtectionMaxCrashes:#{new_resource.rapid_fail_protection_max_crashes}") + end + converge_if_changed :auto_shutdown_exe do + cmd << configure_application_pool("failure.autoShutdownExe:#{new_resource.auto_shutdown_exe}") + end + converge_if_changed :auto_shutdown_params do + cmd << configure_application_pool("failure.autoShutdownParams:#{new_resource.auto_shutdown_params}") + end + + # cpu items + converge_if_changed :cpu_action do + cmd << configure_application_pool("cpu.action:#{new_resource.cpu_action}") + end + converge_if_changed :cpu_limit do + cmd << configure_application_pool("cpu.limit:#{new_resource.cpu_limit}") + end + converge_if_changed :cpu_reset_interval do + cmd << configure_application_pool("cpu.resetInterval:#{new_resource.cpu_reset_interval}") + end + converge_if_changed :cpu_smp_affinitized do + cmd << configure_application_pool("cpu.smpAffinitized:#{new_resource.cpu_smp_affinitized}") + end + converge_if_changed :smp_processor_affinity_mask do + cmd << configure_application_pool("cpu.smpProcessorAffinityMask:#{new_resource.smp_processor_affinity_mask.floor}") + end + converge_if_changed :smp_processor_affinity_mask_2 do + cmd << configure_application_pool("cpu.smpProcessorAffinityMask2:#{new_resource.smp_processor_affinity_mask_2.floor}") + end + + unless current_resource.runtime_version && cmd == "#{appcmd(node)} set config /section:applicationPools" + converge_by "Configured Application Pool \"#{new_resource}\"" do + Chef::Log.debug(cmd) + shell_out!(cmd) + end + end + + # Application Pool Identity Settings + if new_resource.username && new_resource.username != '' + cmd = default_app_pool_user + converge_if_changed :username do + cmd << " \"/[name='#{new_resource.name}'].processModel.userName:#{new_resource.username}\"" + end + converge_if_changed :password do + cmd << " \"/[name='#{new_resource.name}'].processModel.password:#{new_resource.password}\"" + end + if cmd != default_app_pool_user + converge_by "Configured Application Pool Identity Settings \"#{new_resource}\"" do + Chef::Log.debug(cmd) + shell_out!(cmd) + end + end + elsif new_resource.identity_type != 'SpecificUser' + converge_if_changed :identity_type do + cmd = "#{appcmd(node)} set config /section:applicationPools" + cmd << " \"/[name='#{new_resource.name}'].processModel.identityType:#{new_resource.identity_type}\"" + Chef::Log.debug(cmd) + shell_out!(cmd) + end + end + end + + def default_app_pool_user + cmd_default = "#{appcmd(node)} set config /section:applicationPools" + cmd_default << " \"/[name='#{new_resource.name}'].processModel.identityType:SpecificUser\"" + end + + def configure_application_pool(config, add_remove = '') + " \"/#{add_remove}[name='#{new_resource.name}'].#{config}\"" + end +end diff --git a/cookbooks/iis/resources/root.rb b/cookbooks/iis/resources/root.rb index 9fe4fc0..821040f 100644 --- a/cookbooks/iis/resources/root.rb +++ b/cookbooks/iis/resources/root.rb @@ -1,9 +1,8 @@ # -# Author:: Justin Schuhmann () # Cookbook:: iis # Resource:: root # -# Copyright:: 2016, Justin Schuhmann +# Copyright:: 2017, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -18,14 +17,72 @@ # limitations under the License. # -actions :config, :add, :delete +include Opscode::IIS::Constants +include Opscode::IIS::Helper +include Opscode::IIS::Processors + +property :default_documents_enabled, [true, false], default: true +property :default_documents, Array, default: Opscode::IIS::Constants.default_documents +property :mime_maps, Array, default: Opscode::IIS::Constants.default_mime_types +property :add_default_documents, Array, default: [] +property :add_mime_maps, Array, default: [] +property :delete_default_documents, Array, default: [] +property :delete_mime_maps, Array, default: [] + default_action :config -# default documents -attribute :default_documents_enabled, kind_of: [TrueClass, FalseClass], default: true -attribute :default_documents, kind_of: Array, default: ['Default.htm', 'Default.asp', 'index.htm', 'index.html', 'iisstart.htm', 'default.aspx'] -attribute :mime_maps, kind_of: Array, default: ["fileExtension='.323',mimeType='text/h323'", "fileExtension='.3g2',mimeType='video/3gpp2'", "fileExtension='.3gp2',mimeType='video/3gpp2'", "fileExtension='.3gp',mimeType='video/3gpp'", "fileExtension='.3gpp',mimeType='video/3gpp'", "fileExtension='.aaf',mimeType='application/octet-stream'", "fileExtension='.aac',mimeType='audio/aac'", "fileExtension='.aca',mimeType='application/octet-stream'", "fileExtension='.accdb',mimeType='application/msaccess'", "fileExtension='.accde',mimeType='application/msaccess'", "fileExtension='.accdt',mimeType='application/msaccess'", "fileExtension='.acx',mimeType='application/internet-property-stream'", "fileExtension='.adt',mimeType='audio/vnd.dlna.adts'", "fileExtension='.adts',mimeType='audio/vnd.dlna.adts'", "fileExtension='.afm',mimeType='application/octet-stream'", "fileExtension='.ai',mimeType='application/postscript'", "fileExtension='.aif',mimeType='audio/x-aiff'", "fileExtension='.aifc',mimeType='audio/aiff'", "fileExtension='.aiff',mimeType='audio/aiff'", "fileExtension='.application',mimeType='application/x-ms-application'", "fileExtension='.art',mimeType='image/x-jg'", "fileExtension='.asd',mimeType='application/octet-stream'", "fileExtension='.asf',mimeType='video/x-ms-asf'", "fileExtension='.asi',mimeType='application/octet-stream'", "fileExtension='.asm',mimeType='text/plain'", "fileExtension='.asr',mimeType='video/x-ms-asf'", "fileExtension='.asx',mimeType='video/x-ms-asf'", "fileExtension='.atom',mimeType='application/atom+xml'", "fileExtension='.au',mimeType='audio/basic'", "fileExtension='.avi',mimeType='video/avi'", "fileExtension='.axs',mimeType='application/olescript'", "fileExtension='.bas',mimeType='text/plain'", "fileExtension='.bcpio',mimeType='application/x-bcpio'", "fileExtension='.bin',mimeType='application/octet-stream'", "fileExtension='.bmp',mimeType='image/bmp'", "fileExtension='.c',mimeType='text/plain'", "fileExtension='.cab',mimeType='application/vnd.ms-cab-compressed'", "fileExtension='.calx',mimeType='application/vnd.ms-office.calx'", "fileExtension='.cat',mimeType='application/vnd.ms-pki.seccat'", "fileExtension='.cdf',mimeType='application/x-cdf'", "fileExtension='.chm',mimeType='application/octet-stream'", "fileExtension='.class',mimeType='application/x-java-applet'", "fileExtension='.clp',mimeType='application/x-msclip'", "fileExtension='.cmx',mimeType='image/x-cmx'", "fileExtension='.cnf',mimeType='text/plain'", "fileExtension='.cod',mimeType='image/cis-cod'", "fileExtension='.cpio',mimeType='application/x-cpio'", "fileExtension='.cpp',mimeType='text/plain'", "fileExtension='.crd',mimeType='application/x-mscardfile'", "fileExtension='.crl',mimeType='application/pkix-crl'", "fileExtension='.crt',mimeType='application/x-x509-ca-cert'", "fileExtension='.csh',mimeType='application/x-csh'", "fileExtension='.css',mimeType='text/css'", "fileExtension='.csv',mimeType='application/octet-stream'", "fileExtension='.cur',mimeType='application/octet-stream'", "fileExtension='.dcr',mimeType='application/x-director'", "fileExtension='.deploy',mimeType='application/octet-stream'", "fileExtension='.der',mimeType='application/x-x509-ca-cert'", "fileExtension='.dib',mimeType='image/bmp'", "fileExtension='.dir',mimeType='application/x-director'", "fileExtension='.disco',mimeType='text/xml'", "fileExtension='.dll',mimeType='application/x-msdownload'", "fileExtension='.dll.config',mimeType='text/xml'", "fileExtension='.dlm',mimeType='text/dlm'", "fileExtension='.doc',mimeType='application/msword'", "fileExtension='.docm',mimeType='application/vnd.ms-word.document.macroEnabled.12'", "fileExtension='.docx',mimeType='application/vnd.openxmlformats-officedocument.wordprocessingml.document'", "fileExtension='.dot',mimeType='application/msword'", "fileExtension='.dotm',mimeType='application/vnd.ms-word.template.macroEnabled.12'", "fileExtension='.dotx',mimeType='application/vnd.openxmlformats-officedocument.wordprocessingml.template'", "fileExtension='.dsp',mimeType='application/octet-stream'", "fileExtension='.dtd',mimeType='text/xml'", "fileExtension='.dvi',mimeType='application/x-dvi'", "fileExtension='.dvr-ms',mimeType='video/x-ms-dvr'", "fileExtension='.dwf',mimeType='drawing/x-dwf'", "fileExtension='.dwp',mimeType='application/octet-stream'", "fileExtension='.dxr',mimeType='application/x-director'", "fileExtension='.eml',mimeType='message/rfc822'", "fileExtension='.emz',mimeType='application/octet-stream'", "fileExtension='.eot',mimeType='application/vnd.ms-fontobject'", "fileExtension='.eps',mimeType='application/postscript'", "fileExtension='.etx',mimeType='text/x-setext'", "fileExtension='.evy',mimeType='application/envoy'", "fileExtension='.exe',mimeType='application/octet-stream'", "fileExtension='.exe.config',mimeType='text/xml'", "fileExtension='.fdf',mimeType='application/vnd.fdf'", "fileExtension='.fif',mimeType='application/fractals'", "fileExtension='.fla',mimeType='application/octet-stream'", "fileExtension='.flr',mimeType='x-world/x-vrml'", "fileExtension='.flv',mimeType='video/x-flv'", "fileExtension='.gif',mimeType='image/gif'", "fileExtension='.gtar',mimeType='application/x-gtar'", "fileExtension='.gz',mimeType='application/x-gzip'", "fileExtension='.h',mimeType='text/plain'", "fileExtension='.hdf',mimeType='application/x-hdf'", "fileExtension='.hdml',mimeType='text/x-hdml'", "fileExtension='.hhc',mimeType='application/x-oleobject'", "fileExtension='.hhk',mimeType='application/octet-stream'", "fileExtension='.hhp',mimeType='application/octet-stream'", "fileExtension='.hlp',mimeType='application/winhlp'", "fileExtension='.hqx',mimeType='application/mac-binhex40'", "fileExtension='.hta',mimeType='application/hta'", "fileExtension='.htc',mimeType='text/x-component'", "fileExtension='.htm',mimeType='text/html'", "fileExtension='.html',mimeType='text/html'", "fileExtension='.htt',mimeType='text/webviewhtml'", "fileExtension='.hxt',mimeType='text/html'", "fileExtension='.ico',mimeType='image/x-icon'", "fileExtension='.ics',mimeType='text/calendar'", "fileExtension='.ief',mimeType='image/ief'", "fileExtension='.iii',mimeType='application/x-iphone'", "fileExtension='.inf',mimeType='application/octet-stream'", "fileExtension='.ins',mimeType='application/x-internet-signup'", "fileExtension='.isp',mimeType='application/x-internet-signup'", "fileExtension='.IVF',mimeType='video/x-ivf'", "fileExtension='.jar',mimeType='application/java-archive'", "fileExtension='.java',mimeType='application/octet-stream'", "fileExtension='.jck',mimeType='application/liquidmotion'", "fileExtension='.jcz',mimeType='application/liquidmotion'", "fileExtension='.jfif',mimeType='image/pjpeg'", "fileExtension='.jpb',mimeType='application/octet-stream'", "fileExtension='.jpe',mimeType='image/jpeg'", "fileExtension='.jpeg',mimeType='image/jpeg'", "fileExtension='.jpg',mimeType='image/jpeg'", "fileExtension='.js',mimeType='application/javascript'", "fileExtension='.json',mimeType='application/json'", "fileExtension='.jsx',mimeType='text/jscript'", "fileExtension='.latex',mimeType='application/x-latex'", "fileExtension='.lit',mimeType='application/x-ms-reader'", "fileExtension='.lpk',mimeType='application/octet-stream'", "fileExtension='.lsf',mimeType='video/x-la-asf'", "fileExtension='.lsx',mimeType='video/x-la-asf'", "fileExtension='.lzh',mimeType='application/octet-stream'", "fileExtension='.m13',mimeType='application/x-msmediaview'", "fileExtension='.m14',mimeType='application/x-msmediaview'", "fileExtension='.m1v',mimeType='video/mpeg'", "fileExtension='.m2ts',mimeType='video/vnd.dlna.mpeg-tts'", "fileExtension='.m3u',mimeType='audio/x-mpegurl'", "fileExtension='.m4a',mimeType='audio/mp4'", "fileExtension='.m4v',mimeType='video/mp4'", "fileExtension='.man',mimeType='application/x-troff-man'", "fileExtension='.manifest',mimeType='application/x-ms-manifest'", "fileExtension='.map',mimeType='text/plain'", "fileExtension='.mdb',mimeType='application/x-msaccess'", "fileExtension='.mdp',mimeType='application/octet-stream'", "fileExtension='.me',mimeType='application/x-troff-me'", "fileExtension='.mht',mimeType='message/rfc822'", "fileExtension='.mhtml',mimeType='message/rfc822'", "fileExtension='.mid',mimeType='audio/mid'", "fileExtension='.midi',mimeType='audio/mid'", "fileExtension='.mix',mimeType='application/octet-stream'", "fileExtension='.mmf',mimeType='application/x-smaf'", "fileExtension='.mno',mimeType='text/xml'", "fileExtension='.mny',mimeType='application/x-msmoney'", "fileExtension='.mov',mimeType='video/quicktime'", "fileExtension='.movie',mimeType='video/x-sgi-movie'", "fileExtension='.mp2',mimeType='video/mpeg'", "fileExtension='.mp3',mimeType='audio/mpeg'", "fileExtension='.mp4',mimeType='video/mp4'", "fileExtension='.mp4v',mimeType='video/mp4'", "fileExtension='.mpa',mimeType='video/mpeg'", "fileExtension='.mpe',mimeType='video/mpeg'", "fileExtension='.mpeg',mimeType='video/mpeg'", "fileExtension='.mpg',mimeType='video/mpeg'", "fileExtension='.mpp',mimeType='application/vnd.ms-project'", "fileExtension='.mpv2',mimeType='video/mpeg'", "fileExtension='.ms',mimeType='application/x-troff-ms'", "fileExtension='.msi',mimeType='application/octet-stream'", "fileExtension='.mso',mimeType='application/octet-stream'", "fileExtension='.mvb',mimeType='application/x-msmediaview'", "fileExtension='.mvc',mimeType='application/x-miva-compiled'", "fileExtension='.nc',mimeType='application/x-netcdf'", "fileExtension='.nsc',mimeType='video/x-ms-asf'", "fileExtension='.nws',mimeType='message/rfc822'", "fileExtension='.ocx',mimeType='application/octet-stream'", "fileExtension='.oda',mimeType='application/oda'", "fileExtension='.odc',mimeType='text/x-ms-odc'", "fileExtension='.ods',mimeType='application/oleobject'", "fileExtension='.oga',mimeType='audio/ogg'", "fileExtension='.ogg',mimeType='video/ogg'", "fileExtension='.ogv',mimeType='video/ogg'", "fileExtension='.one',mimeType='application/onenote'", "fileExtension='.onea',mimeType='application/onenote'", "fileExtension='.onetoc',mimeType='application/onenote'", "fileExtension='.onetoc2',mimeType='application/onenote'", "fileExtension='.onetmp',mimeType='application/onenote'", "fileExtension='.onepkg',mimeType='application/onenote'", "fileExtension='.osdx',mimeType='application/opensearchdescription+xml'", "fileExtension='.otf',mimeType='font/otf'", "fileExtension='.p10',mimeType='application/pkcs10'", "fileExtension='.p12',mimeType='application/x-pkcs12'", "fileExtension='.p7b',mimeType='application/x-pkcs7-certificates'", "fileExtension='.p7c',mimeType='application/pkcs7-mime'", "fileExtension='.p7m',mimeType='application/pkcs7-mime'", "fileExtension='.p7r',mimeType='application/x-pkcs7-certreqresp'", "fileExtension='.p7s',mimeType='application/pkcs7-signature'", "fileExtension='.pbm',mimeType='image/x-portable-bitmap'", "fileExtension='.pcx',mimeType='application/octet-stream'", "fileExtension='.pcz',mimeType='application/octet-stream'", "fileExtension='.pdf',mimeType='application/pdf'", "fileExtension='.pfb',mimeType='application/octet-stream'", "fileExtension='.pfm',mimeType='application/octet-stream'", "fileExtension='.pfx',mimeType='application/x-pkcs12'", "fileExtension='.pgm',mimeType='image/x-portable-graymap'", "fileExtension='.pko',mimeType='application/vnd.ms-pki.pko'", "fileExtension='.pma',mimeType='application/x-perfmon'", "fileExtension='.pmc',mimeType='application/x-perfmon'", "fileExtension='.pml',mimeType='application/x-perfmon'", "fileExtension='.pmr',mimeType='application/x-perfmon'", "fileExtension='.pmw',mimeType='application/x-perfmon'", "fileExtension='.png',mimeType='image/png'", "fileExtension='.pnm',mimeType='image/x-portable-anymap'", "fileExtension='.pnz',mimeType='image/png'", "fileExtension='.pot',mimeType='application/vnd.ms-powerpoint'", "fileExtension='.potm',mimeType='application/vnd.ms-powerpoint.template.macroEnabled.12'", "fileExtension='.potx',mimeType='application/vnd.openxmlformats-officedocument.presentationml.template'", "fileExtension='.ppam',mimeType='application/vnd.ms-powerpoint.addin.macroEnabled.12'", "fileExtension='.ppm',mimeType='image/x-portable-pixmap'", "fileExtension='.pps',mimeType='application/vnd.ms-powerpoint'", "fileExtension='.ppsm',mimeType='application/vnd.ms-powerpoint.slideshow.macroEnabled.12'", "fileExtension='.ppsx',mimeType='application/vnd.openxmlformats-officedocument.presentationml.slideshow'", "fileExtension='.ppt',mimeType='application/vnd.ms-powerpoint'", "fileExtension='.pptm',mimeType='application/vnd.ms-powerpoint.presentation.macroEnabled.12'", "fileExtension='.pptx',mimeType='application/vnd.openxmlformats-officedocument.presentationml.presentation'", "fileExtension='.prf',mimeType='application/pics-rules'", "fileExtension='.prm',mimeType='application/octet-stream'", "fileExtension='.prx',mimeType='application/octet-stream'", "fileExtension='.ps',mimeType='application/postscript'", "fileExtension='.psd',mimeType='application/octet-stream'", "fileExtension='.psm',mimeType='application/octet-stream'", "fileExtension='.psp',mimeType='application/octet-stream'", "fileExtension='.pub',mimeType='application/x-mspublisher'", "fileExtension='.qt',mimeType='video/quicktime'", "fileExtension='.qtl',mimeType='application/x-quicktimeplayer'", "fileExtension='.qxd',mimeType='application/octet-stream'", "fileExtension='.ra',mimeType='audio/x-pn-realaudio'", "fileExtension='.ram',mimeType='audio/x-pn-realaudio'", "fileExtension='.rar',mimeType='application/octet-stream'", "fileExtension='.ras',mimeType='image/x-cmu-raster'", "fileExtension='.rf',mimeType='image/vnd.rn-realflash'", "fileExtension='.rgb',mimeType='image/x-rgb'", "fileExtension='.rm',mimeType='application/vnd.rn-realmedia'", "fileExtension='.rmi',mimeType='audio/mid'", "fileExtension='.roff',mimeType='application/x-troff'", "fileExtension='.rpm',mimeType='audio/x-pn-realaudio-plugin'", "fileExtension='.rtf',mimeType='application/rtf'", "fileExtension='.rtx',mimeType='text/richtext'", "fileExtension='.scd',mimeType='application/x-msschedule'", "fileExtension='.sct',mimeType='text/scriptlet'", "fileExtension='.sea',mimeType='application/octet-stream'", "fileExtension='.setpay',mimeType='application/set-payment-initiation'", "fileExtension='.setreg',mimeType='application/set-registration-initiation'", "fileExtension='.sgml',mimeType='text/sgml'", "fileExtension='.sh',mimeType='application/x-sh'", "fileExtension='.shar',mimeType='application/x-shar'", "fileExtension='.sit',mimeType='application/x-stuffit'", "fileExtension='.sldm',mimeType='application/vnd.ms-powerpoint.slide.macroEnabled.12'", "fileExtension='.sldx',mimeType='application/vnd.openxmlformats-officedocument.presentationml.slide'", "fileExtension='.smd',mimeType='audio/x-smd'", "fileExtension='.smi',mimeType='application/octet-stream'", "fileExtension='.smx',mimeType='audio/x-smd'", "fileExtension='.smz',mimeType='audio/x-smd'", "fileExtension='.snd',mimeType='audio/basic'", "fileExtension='.snp',mimeType='application/octet-stream'", "fileExtension='.spc',mimeType='application/x-pkcs7-certificates'", "fileExtension='.spl',mimeType='application/futuresplash'", "fileExtension='.spx',mimeType='audio/ogg'", "fileExtension='.src',mimeType='application/x-wais-source'", "fileExtension='.ssm',mimeType='application/streamingmedia'", "fileExtension='.sst',mimeType='application/vnd.ms-pki.certstore'", "fileExtension='.stl',mimeType='application/vnd.ms-pki.stl'", "fileExtension='.sv4cpio',mimeType='application/x-sv4cpio'", "fileExtension='.sv4crc',mimeType='application/x-sv4crc'", "fileExtension='.svg',mimeType='image/svg+xml'", "fileExtension='.svgz',mimeType='image/svg+xml'", "fileExtension='.swf',mimeType='application/x-shockwave-flash'", "fileExtension='.t',mimeType='application/x-troff'", "fileExtension='.tar',mimeType='application/x-tar'", "fileExtension='.tcl',mimeType='application/x-tcl'", "fileExtension='.tex',mimeType='application/x-tex'", "fileExtension='.texi',mimeType='application/x-texinfo'", "fileExtension='.texinfo',mimeType='application/x-texinfo'", "fileExtension='.tgz',mimeType='application/x-compressed'", "fileExtension='.thmx',mimeType='application/vnd.ms-officetheme'", "fileExtension='.thn',mimeType='application/octet-stream'", "fileExtension='.tif',mimeType='image/tiff'", "fileExtension='.tiff',mimeType='image/tiff'", "fileExtension='.toc',mimeType='application/octet-stream'", "fileExtension='.tr',mimeType='application/x-troff'", "fileExtension='.trm',mimeType='application/x-msterminal'", "fileExtension='.ts',mimeType='video/vnd.dlna.mpeg-tts'", "fileExtension='.tsv',mimeType='text/tab-separated-values'", "fileExtension='.ttf',mimeType='application/octet-stream'", "fileExtension='.tts',mimeType='video/vnd.dlna.mpeg-tts'", "fileExtension='.txt',mimeType='text/plain'", "fileExtension='.u32',mimeType='application/octet-stream'", "fileExtension='.uls',mimeType='text/iuls'", "fileExtension='.ustar',mimeType='application/x-ustar'", "fileExtension='.vbs',mimeType='text/vbscript'", "fileExtension='.vcf',mimeType='text/x-vcard'", "fileExtension='.vcs',mimeType='text/plain'", "fileExtension='.vdx',mimeType='application/vnd.ms-visio.viewer'", "fileExtension='.vml',mimeType='text/xml'", "fileExtension='.vsd',mimeType='application/vnd.visio'", "fileExtension='.vss',mimeType='application/vnd.visio'", "fileExtension='.vst',mimeType='application/vnd.visio'", "fileExtension='.vsto',mimeType='application/x-ms-vsto'", "fileExtension='.vsw',mimeType='application/vnd.visio'", "fileExtension='.vsx',mimeType='application/vnd.visio'", "fileExtension='.vtx',mimeType='application/vnd.visio'", "fileExtension='.wav',mimeType='audio/wav'", "fileExtension='.wax',mimeType='audio/x-ms-wax'", "fileExtension='.wbmp',mimeType='image/vnd.wap.wbmp'", "fileExtension='.wcm',mimeType='application/vnd.ms-works'", "fileExtension='.wdb',mimeType='application/vnd.ms-works'", "fileExtension='.webm',mimeType='video/webm'", "fileExtension='.wks',mimeType='application/vnd.ms-works'", "fileExtension='.wm',mimeType='video/x-ms-wm'", "fileExtension='.wma',mimeType='audio/x-ms-wma'", "fileExtension='.wmd',mimeType='application/x-ms-wmd'", "fileExtension='.wmf',mimeType='application/x-msmetafile'", "fileExtension='.wml',mimeType='text/vnd.wap.wml'", "fileExtension='.wmlc',mimeType='application/vnd.wap.wmlc'", "fileExtension='.wmls',mimeType='text/vnd.wap.wmlscript'", "fileExtension='.wmlsc',mimeType='application/vnd.wap.wmlscriptc'", "fileExtension='.wmp',mimeType='video/x-ms-wmp'", "fileExtension='.wmv',mimeType='video/x-ms-wmv'", "fileExtension='.wmx',mimeType='video/x-ms-wmx'", "fileExtension='.wmz',mimeType='application/x-ms-wmz'", "fileExtension='.woff',mimeType='font/x-woff'", "fileExtension='.wps',mimeType='application/vnd.ms-works'", "fileExtension='.wri',mimeType='application/x-mswrite'", "fileExtension='.wrl',mimeType='x-world/x-vrml'", "fileExtension='.wrz',mimeType='x-world/x-vrml'", "fileExtension='.wsdl',mimeType='text/xml'", "fileExtension='.wtv',mimeType='video/x-ms-wtv'", "fileExtension='.wvx',mimeType='video/x-ms-wvx'", "fileExtension='.x',mimeType='application/directx'", "fileExtension='.xaf',mimeType='x-world/x-vrml'", "fileExtension='.xaml',mimeType='application/xaml+xml'", "fileExtension='.xap',mimeType='application/x-silverlight-app'", "fileExtension='.xbap',mimeType='application/x-ms-xbap'", "fileExtension='.xbm',mimeType='image/x-xbitmap'", "fileExtension='.xdr',mimeType='text/plain'", "fileExtension='.xht',mimeType='application/xhtml+xml'", "fileExtension='.xhtml',mimeType='application/xhtml+xml'", "fileExtension='.xla',mimeType='application/vnd.ms-excel'", "fileExtension='.xlam',mimeType='application/vnd.ms-excel.addin.macroEnabled.12'", "fileExtension='.xlc',mimeType='application/vnd.ms-excel'", "fileExtension='.xlm',mimeType='application/vnd.ms-excel'", "fileExtension='.xls',mimeType='application/vnd.ms-excel'", "fileExtension='.xlsb',mimeType='application/vnd.ms-excel.sheet.binary.macroEnabled.12'", "fileExtension='.xlsm',mimeType='application/vnd.ms-excel.sheet.macroEnabled.12'", "fileExtension='.xlsx',mimeType='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'", "fileExtension='.xlt',mimeType='application/vnd.ms-excel'", "fileExtension='.xltm',mimeType='application/vnd.ms-excel.template.macroEnabled.12'", "fileExtension='.xltx',mimeType='application/vnd.openxmlformats-officedocument.spreadsheetml.template'", "fileExtension='.xlw',mimeType='application/vnd.ms-excel'", "fileExtension='.xml',mimeType='text/xml'", "fileExtension='.xof',mimeType='x-world/x-vrml'", "fileExtension='.xpm',mimeType='image/x-xpixmap'", "fileExtension='.xps',mimeType='application/vnd.ms-xpsdocument'", "fileExtension='.xsd',mimeType='text/xml'", "fileExtension='.xsf',mimeType='text/xml'", "fileExtension='.xsl',mimeType='text/xml'", "fileExtension='.xslt',mimeType='text/xml'", "fileExtension='.xsn',mimeType='application/octet-stream'", "fileExtension='.xtp',mimeType='application/octet-stream'", "fileExtension='.xwd',mimeType='image/x-xwindowdump'", "fileExtension='.z',mimeType='application/x-compress'", "fileExtension='.zip',mimeType='application/x-zip-compressed'"] -attribute :add_default_documents, kind_of: Array, default: [] -attribute :delete_default_documents, kind_of: Array, default: [] -attribute :add_mime_maps, kind_of: Array, default: [] -attribute :delete_mime_maps, kind_of: Array, default: [] +load_current_value do |desired| + current_default_documents_object = current_default_documents_config + return unless current_default_documents_object + + current_mime_maps = current_mime_maps_config + return unless current_mime_maps_config + + default_documents_enabled bool(current_default_documents_object[:default_documents_enabled]) + default_documents current_default_documents_object[:default_documents] + mime_maps current_mime_maps + + current_add_default_documents = desired.add_default_documents - current_default_documents_object[:default_documents] + add_default_documents desired.add_default_documents - current_add_default_documents + + delete_default_documents desired.delete_default_documents - current_default_documents_object[:default_documents] + + current_add_mime_maps = desired.add_mime_maps - current_mime_maps + add_mime_maps desired.add_mime_maps - current_add_mime_maps + + delete_mime_maps desired.delete_mime_maps - current_mime_maps +end + +action :config do + converge_if_changed :default_documents_enabled do + set_default_documents_enabled(new_resource.default_documents_enabled) + end + + converge_if_changed :default_documents do + set_default_documents(new_resource.default_documents, current_resource.default_documents) + end + + converge_if_changed :mime_maps do + set_mime_maps(new_resource.mime_maps, current_resource.mime_maps) + end +end + +action :add do + converge_if_changed :add_default_documents do + set_default_documents(new_resource.add_default_documents, current_resource.add_default_documents, true, false) + end + + converge_if_changed :add_mime_maps do + set_mime_maps(new_resource.add_mime_maps, current_resource.add_mime_maps, true, false) + end +end + +action :delete do + converge_if_changed :delete_default_documents do + set_default_documents(new_resource.delete_default_documents, current_resource.delete_default_documents, false, true) + end + + converge_if_changed :delete_mime_maps do + set_mime_maps(new_resource.delete_mime_maps, current_resource.delete_mime_maps, false, true) + end +end diff --git a/cookbooks/iis/resources/section.rb b/cookbooks/iis/resources/section.rb index e7e6a03..b7a49c0 100644 --- a/cookbooks/iis/resources/section.rb +++ b/cookbooks/iis/resources/section.rb @@ -1,9 +1,8 @@ # -# Author:: Justin Schuhmann # Cookbook:: iis -# Resource:: lock +# Resource:: section # -# Copyright:: 2016, Justin Schuhmann +# Copyright:: 2016-2017, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -18,10 +17,57 @@ # limitations under the License. # -actions :lock, :unlock -default_action :lock +require 'rexml/document' -attribute :section, kind_of: String -attribute :returns, kind_of: [Integer, Array], default: 0 +include REXML +include Opscode::IIS::Helper +include Opscode::IIS::SectionHelper +include Opscode::IIS::Processors -attr_accessor :exists +property :section, String, name_property: true +property :site, String +property :application_path, String +property :returns, [Integer, Array], default: 0 +property :locked, String + +default_action :unlock + +load_current_value do |desired| + section desired.section + site desired.site + application_path desired.application_path + command_path = 'MACHINE/WEBROOT/APPHOST' + command_path << "/#{site}" if site + command_path << application_path.to_s if application_path + cmd = "#{appcmd(node)} list config \"#{command_path}\"" + cmd << " -section:\"#{section}\" /commit:apphost /config:* /xml" + Chef::Log.debug(cmd) + cmd = shell_out(cmd) + if cmd.stderr.empty? + xml = cmd.stdout + doc = Document.new(xml) + locked value doc.root, 'CONFIG/@overrideMode' + else + Chef::Log.info(cmd.stderr) + end +end + +action :lock do + if current_resource.locked != 'Deny' + converge_by "Locking the section - \"#{new_resource}\"" do + lock node, new_resource.section, "#{new_resource.site}#{new_resource.application_path}", new_resource.returns + end + else + Chef::Log.debug("#{new_resource} already locked - nothing to do") + end +end + +action :unlock do + if current_resource.locked != 'Allow' + converge_by "Unlocking the section - \"#{new_resource}\"" do + unlock node, new_resource.section, "#{new_resource.site}#{new_resource.application_path}", new_resource.returns + end + else + Chef::Log.debug("#{new_resource} already unlocked - nothing to do") + end +end diff --git a/cookbooks/iis/resources/site.rb b/cookbooks/iis/resources/site.rb index 69a8914..2a0a654 100644 --- a/cookbooks/iis/resources/site.rb +++ b/cookbooks/iis/resources/site.rb @@ -1,9 +1,8 @@ # -# Author:: Seth Chisamore () # Cookbook:: iis # Resource:: site # -# Copyright:: 2011-2016, Chef Software, Inc. +# Copyright:: 2017, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -18,20 +17,219 @@ # limitations under the License. # -actions :add, :delete, :start, :stop, :restart, :config +require 'rexml/document' + +include REXML +include Opscode::IIS::Helper +include Opscode::IIS::Processors + +property :site_name, String, name_property: true +property :site_id, Integer +property :port, Integer, default: 80, coerce: proc { |v| v.to_i } +property :path, String +property :protocol, [Symbol, String], equal_to: [:http, :https], default: :http, coerce: proc { |v| v.to_sym } +property :host_header, String +property :bindings, String +property :application_pool, String +property :options, String, default: '' +property :log_directory, String, default: node['iis']['log_dir'] +property :log_period, [Symbol, String], equal_to: [:Daily, :Hourly, :MaxSize, :Monthly, :Weekly], default: :Daily, coerce: proc { |v| v.to_sym } +property :log_truncsize, Integer, default: 1_048_576 +property :running, [true, false], desired_state: true + default_action :add -attribute :site_name, kind_of: String, name_attribute: true -attribute :site_id, kind_of: Integer -attribute :port, kind_of: Integer, default: 80 -attribute :path, kind_of: String -attribute :protocol, kind_of: Symbol, default: :http, equal_to: [:http, :https] -attribute :host_header, kind_of: String, default: nil -attribute :bindings, kind_of: String, default: nil -attribute :application_pool, kind_of: String, default: nil -attribute :options, kind_of: String, default: '' -attribute :log_directory, kind_of: String, default: node['iis']['log_dir'] -attribute :log_period, kind_of: Symbol, default: :Daily, equal_to: [:Daily, :Hourly, :MaxSize, :Monthly, :Weekly] -attribute :log_truncsize, kind_of: Integer, default: 1_048_576 +load_current_value do |desired| + site_name desired.site_name + # Sanitize windows file system path + desired.path = windows_cleanpath(desired.path) if desired.path + desired.log_directory = windows_cleanpath(desired.log_directory) if desired.log_directory + cmd = shell_out "#{appcmd(node)} list site \"#{site_name}\"" + Chef::Log.debug(appcmd(node)) + # 'SITE "Default Web Site" (id:1,bindings:http/*:80:,state:Started)' + Chef::Log.debug("#{desired} list site command output: #{cmd.stdout}") + if cmd.stderr.empty? + result = cmd.stdout.gsub(/\r\n?/, "\n") # ensure we have no carriage returns + result = result.match(/^SITE\s\"(?#{desired.site_name})\"\s\(id:(?.*),bindings:(?.*),state:(?.*)\)$/i) + Chef::Log.debug("#{desired} current_resource match output: #{result}") + if result + site_id result[:site_id].to_i + bindings result[:bindings] + running result[:state] =~ /Started/ ? true : false + else + running false + end -attr_accessor :exists, :running + if site_id + values = "#{bindings},".match(%r{(?[^\/]+)\/\*:(?[^:]+):(?[^,]*),}) + # get current values + cmd = "#{appcmd(node)} list site \"#{site_name}\" /config:* /xml" + Chef::Log.debug(cmd) + cmd = shell_out cmd + if cmd.stderr.empty? + xml = cmd.stdout + doc = Document.new(xml) + path windows_cleanpath(value(doc.root, 'SITE/site/application/virtualDirectory/@physicalPath')) + log_directory windows_cleanpath(value(doc.root, 'SITE/site/logFile/@directory')) + log_period value(doc.root, 'SITE/site/logFile/@period').to_sym + log_truncsize value(doc.root, 'SITE/site/logFile/@truncateSize').to_i + application_pool value doc.root, 'SITE/site/application/@applicationPool' + end + + if values + protocol values[:protocol].to_sym + port values[:port].to_i + host_header values[:host_header] + end + else + running false + end + + if values + protocol values[:protocol] + port values[:port].to_i + host_header values[:host_header] + end + else + Chef::Log.warn "Failed to run iis_site action :config, #{cmd.stderr}" + end +end + +action :add do + if exists + Chef::Log.debug("#{new_resource} site already exists - nothing to do") + else + converge_by "Created the Site - \"#{new_resource}\"" do + cmd = "#{appcmd(node)} add site /name:\"#{new_resource.site_name}\"" + cmd << " /id:#{new_resource.site_id}" if new_resource.site_id + cmd << " /physicalPath:\"#{new_resource.path}\"" if new_resource.path + if new_resource.bindings + cmd << " /bindings:\"#{new_resource.bindings}\"" + else + cmd << " /bindings:#{new_resource.protocol}/*" + cmd << ":#{new_resource.port}:" if new_resource.port + cmd << new_resource.host_header if new_resource.host_header + end + + # support for additional options -logDir, -limits, -ftpServer, etc... + cmd << " #{new_resource.options}" if new_resource.options + shell_out!(cmd, returns: [0, 42]) + + configure + + if new_resource.application_pool + shell_out!("#{appcmd(node)} set site /site.name:\"#{new_resource.site_name}\" /[path='/'].applicationPool:\"#{new_resource.application_pool}\"", returns: [0, 42]) + end + Chef::Log.info("#{new_resource} added new site '#{new_resource.site_name}'") + end + end +end + +action :config do + configure if exists +end + +action :delete do + if exists + converge_by "Deleted the Site - \"#{new_resource}\"" do + Chef::Log.info("#{appcmd(node)} stop site /site.name:\"#{new_resource.site_name}\"") + shell_out!("#{appcmd(node)} delete site /site.name:\"#{new_resource.site_name}\"", returns: [0, 42]) + end + else + Chef::Log.debug("#{new_resource} site does not exist - nothing to do") + end +end + +action :start do + if exists && !current_resource.running + converge_by "Started the Site - \"#{new_resource}\"" do + shell_out!("#{appcmd(node)} start site /site.name:\"#{new_resource.site_name}\"", returns: [0, 42]) + end + else + Chef::Log.debug("#{new_resource} already running - nothing to do") + end +end + +action :stop do + if exists && current_resource.running + converge_by "Stopped the Site - \"#{new_resource}\"" do + Chef::Log.info("#{appcmd(node)} stop site /site.name:\"#{new_resource.site_name}\"") + shell_out!("#{appcmd(node)} stop site /site.name:\"#{new_resource.site_name}\"", returns: [0, 42]) + end + else + Chef::Log.debug("#{new_resource} already stopped - nothing to do") + end +end + +action :restart do + converge_by "Restarted the Site - \"#{new_resource}\"" do + shell_out!("#{appcmd(node)} stop site /site.name:\"#{new_resource.site_name}\"", returns: [0, 42]) if running + sleep 2 + shell_out!("#{appcmd(node)} start site /site.name:\"#{new_resource.site_name}\"", returns: [0, 42]) + end +end + +action_class.class_eval do + def exists + current_resource.site_id ? true : false + end + + def configure + if new_resource.bindings + converge_if_changed :bindings do + cmd = "#{appcmd(node)} set site /site.name:\"#{new_resource.site_name}\"" + cmd << " /bindings:\"#{new_resource.bindings}\"" + Chef::Log.debug(cmd) + shell_out!(cmd) + end + elsif new_resource.port || new_resource.host_header || new_resource.protocol + converge_if_changed :bindings, :host_header, :protocol do + cmd = "#{appcmd(node)} set site \"#{new_resource.site_name}\"" + cmd << " /bindings:#{new_resource.protocol}/*:#{new_resource.port}:#{new_resource.host_header}" + Chef::Log.debug(cmd) + shell_out!(cmd) + end + end + + converge_if_changed :application_pool do + cmd = "#{appcmd(node)} set app \"#{new_resource.site_name}/\" /applicationPool:\"#{new_resource.application_pool}\"" + Chef::Log.debug(cmd) + shell_out!(cmd, returns: [0, 42]) + end + + converge_if_changed :path do + cmd = "#{appcmd(node)} set vdir \"#{new_resource.site_name}/\"" + cmd << " /physicalPath:\"#{new_resource.path}\"" + Chef::Log.debug(cmd) + shell_out!(cmd) + end + + converge_if_changed :site_id do + cmd = "#{appcmd(node)} set site \"#{new_resource.site_name}\"" + cmd << " /id:#{new_resource.site_id}" + Chef::Log.debug(cmd) + shell_out!(cmd) + end + + converge_if_changed :log_directory do + cmd = "#{appcmd(node)} set site \"#{new_resource.site_name}\"" + cmd << " /logFile.directory:#{new_resource.log_directory}" + Chef::Log.debug(cmd) + shell_out!(cmd) + end + + converge_if_changed :log_period do + cmd = "#{appcmd(node)} set site \"#{new_resource.site_name}\"" + cmd << " /logFile.period:#{new_resource.log_period}" + Chef::Log.debug(cmd) + shell_out!(cmd) + end + + converge_if_changed :log_truncsize do + cmd = "#{appcmd(node)} set site \"#{new_resource.site_name}\"" + cmd << " /logFile.truncateSize:#{new_resource.log_truncsize}" + Chef::Log.debug(cmd) + shell_out!(cmd) + end + end +end diff --git a/cookbooks/iis/resources/vdir.rb b/cookbooks/iis/resources/vdir.rb index 913d16b..594d71c 100644 --- a/cookbooks/iis/resources/vdir.rb +++ b/cookbooks/iis/resources/vdir.rb @@ -1,9 +1,8 @@ # -# Author:: Justin Schuhmann () # Cookbook:: iis -# Resource:: site +# Resource:: vdir # -# Copyright:: 2016, Justin Schuhmann +# Copyright:: 2016-2017, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -18,15 +17,128 @@ # limitations under the License. # -actions :add, :delete, :config +require 'rexml/document' + +include REXML +include Opscode::IIS::Helper +include Opscode::IIS::Processors + +property :application_name, String, name_property: true +property :path, String +property :physical_path, String +property :username, String +property :password, String +property :logon_method, [Symbol, String], default: :ClearText, equal_to: [:Interactive, :Batch, :Network, :ClearText], coerce: proc { |v| v.to_sym } +property :allow_sub_dir_config, [true, false], default: true + default_action :add -attribute :application_name, kind_of: String, name_attribute: true -attribute :path, kind_of: String -attribute :physical_path, kind_of: String -attribute :username, kind_of: String, default: nil -attribute :password, kind_of: String, default: nil -attribute :logon_method, kind_of: Symbol, default: :ClearText, equal_to: [:Interactive, :Batch, :Network, :ClearText] -attribute :allow_sub_dir_config, kind_of: [TrueClass, FalseClass], default: true +load_current_value do |desired| + # Sanitize Application Name + desired.application_name = application_cleanname(desired.application_name) + # Sanitize Physical Path + desired.physical_path = windows_cleanpath(desired.physical_path) if desired.physical_path + application_name desired.application_name + path desired.path + cmd = shell_out("#{appcmd(node)} list vdir \"#{application_name.chomp('/') + path}\"") + Chef::Log.debug("#{desired} list vdir command output: #{cmd.stdout}") -attr_accessor :exists + if cmd.stderr.empty? + # VDIR "Testfu Site/Content/Test" + result = cmd.stdout.match(/^VDIR\s\"#{Regexp.escape(application_name.chomp('/') + path)}\"/) + Chef::Log.debug("#{desired} current_resource match output: #{result}") + unless result.nil? + cmd = shell_out("#{appcmd(node)} list vdir \"#{application_name.chomp('/') + path}\" /config:* /xml") + if cmd.stderr.empty? + xml = cmd.stdout + doc = Document.new(xml) + physical_path windows_cleanpath(value(doc.root, 'VDIR/@physicalPath')) + username value doc.root, 'VDIR/virtualDirectory/@userName' + password value doc.root, 'VDIR/virtualDirectory/@password' + logon_method value(doc.root, 'VDIR/virtualDirectory/@logonMethod').to_sym + allow_sub_dir_config bool(value(doc.root, 'VDIR/virtualDirectory/@allowSubDirConfig')) + end + end + else + Chef::Log.warn "Failed to run iis_vdir action :load_current_resource, #{cmd.stderr}" + end +end + +action :add do + if exists + Chef::Log.debug("#{new_resource} virtual directory already exists - nothing to do") + else + converge_by "Created the VDIR - \"#{new_resource}\"" do + cmd = "#{appcmd(node)} add vdir /app.name:\"#{vdir_identifier}\"" + cmd << " /path:\"#{new_resource.path}\"" + cmd << " /physicalPath:\"#{new_resource.physical_path}\"" + cmd << " /userName:\"#{new_resource.username}\"" if new_resource.username + cmd << " /password:\"#{new_resource.password}\"" if new_resource.password + cmd << " /logonMethod:#{new_resource.logon_method}" if new_resource.logon_method + cmd << " /allowSubDirConfig:#{new_resource.allow_sub_dir_config}" if new_resource.allow_sub_dir_config + cmd << ' /commit:\"MACHINE/WEBROOT/APPHOST\"' + + Chef::Log.debug(cmd) + shell_out!(cmd, returns: [0, 42, 183]) + end + end +end + +action :config do + if exists + cmd = "#{appcmd(node)} set vdir \"#{application_identifier}\"" + converge_if_changed :physical_path do + cmd << " /physicalPath:\"#{new_resource.physical_path}\"" + end + + converge_if_changed :username do + cmd << " /userName:\"#{new_resource.username}\"" + end + + converge_if_changed :password do + cmd << " /password:\"#{new_resource.password}\"" + end + + converge_if_changed :logon_method do + cmd << " /logonMethod:#{new_resource.logon_method}" + end + + converge_if_changed :allow_sub_dir_config do + cmd << " /allowSubDirConfig:#{new_resource.allow_sub_dir_config}" + end + + if cmd != "#{appcmd(node)} set vdir \"#{application_identifier}\"" + converge_by "Updated the VDIR - \"#{new_resource}\"" do + Chef::Log.debug(cmd) + shell_out!(cmd) + end + else + Chef::Log.debug("#{new_resource} virtual directory - nothing changed") + end + end +end + +action :delete do + if exists + converge_by "Deleted the VDIR - \"#{new_resource}\"" do + Chef::Log.debug("#{appcmd(node)} delete vdir \"#{application_identifier}\"") + shell_out!("#{appcmd(node)} delete vdir \"#{application_identifier}\"", returns: [0, 42]) + end + else + Chef::Log.debug("#{new_resource} virtual directory does not exist - nothing to do") + end +end + +action_class.class_eval do + def exists + current_resource.physical_path ? true : false + end + + def application_identifier + new_resource.path.start_with?('/') ? vdir_identifier.chomp('/') + new_resource.path : vdir_identifier + new_resource.path + end + + def vdir_identifier + new_resource.application_name.include?('/') ? new_resource.application_name : new_resource.application_name + '/' + end +end diff --git a/cookbooks/mysql/CHANGELOG.md b/cookbooks/mysql/CHANGELOG.md index 0e01d05..8fd0aa8 100644 --- a/cookbooks/mysql/CHANGELOG.md +++ b/cookbooks/mysql/CHANGELOG.md @@ -2,94 +2,6 @@ This file is used to list changes made in each version of the mysql cookbook. -## 8.4.0 (2017-05-30) - -- Fix client/server install on Amazon Linux and add testing -- Remove support for Ubuntu Precise since it's EOL -- Add Amazon Linux testing - -## 8.3.1 (2017-04-04) - -- Fix an ignoring of 'cookbook' attribute by 'mysql_config' resource -- Remove unused helper method -- Call out the supported platform versions in the metadata -- Switch to Delivery Local and rename the docked config -- Remove mention of the EOL opensuse 13.x in the readme - -## 8.3.0 (2017-03-20) -- Refactor mysql_service_manager_upstart.rb to eliminate use of cloned resource - -## 8.2.0 (2016-12-03) - -- Include client development packages on RHEL/SUSE platforms - -## 8.1.1 (2016-10-31) -- Fixing CVE-2016-6662 - Reverting execure bit on mysql config - -## 8.1.0 (2016-10-29) - -- Drop hardcoded, specific package version logic that broke many users - -## 8.0.4 (2016-09-26) -- Bump debian version -- Updated packages for 12.04 and 14.04 too -- Add chef_version metadata -- Update platforms in the kitchen file -- Add selinux to the Berksfile for testing -- Make sure yum repos are setup in local Test Kitchen - -## 8.0.3 (2016-09-14) -- [GH-390] Fix #390 incorrect escaping of initial_root_password -- Updated package versions for Ubuntu 16.04 -- Testing updates - -# v8.0.2 (2016-08-25) -- Various bug fixed and updates to package version strings - -# v8.0.1 (2016-07-20) -- Fixed a regression in the mysql_client resource where the action was changed from create to install in the 8.0 release -- Added oracle, opensuse, and opensuseleap as supported platforms in the metadata - -# v8.0.0 (2016-07-11) - -- Converting from LWRP to custom resources -- Removing yum-mysql and other dependencies. -- ^ BREAKING CHANGE: RHELish users are now responsible - for including a recipe from the "yum-mysql" or equivalent - cookbook before utilizing the mysql_* resources. -- More thoughtful ChefSpec -- Renaming "replication" test suite to "smoke" -- Moving to Inspec - -## v7.2.0 (2016-06-30) - -- Support openeSUSE leap -- Support Fedora 24 - -## v7.1.2 (2016-06-30) - -- Avoid deprecation warnings on the upcoming Chef 12.12 release - -## v7.1.1 (2016-06-03) - -- Fix apparmor blocking writes to non-default tmp_dirs -- Updated apparmor config to allow read & write to sock.lock file -- Use cookstyle instead of Rubocop directly - -## v7.1.0 (2016-05-11) - -- Added support for Ubuntu 16.04 - -## v7.0.0 (2016-04-19) - -- Removed support for legacy distros: Ubuntu 10.04/13.04/14.10/15.04, Fedora 20/21, OmniOS r151006, opensuse 11.3/12.0 -- Added support for Fedora 23, suse 13.X, and Ubuntu 16.04 -- Updated the systemd support to create unit files in /etc/systemd and not /usr/lib/systemd -- Adding umask to bash resource that sets root password PR #386 @gziskind -- Cleaned up the Test Kitchen config to test the right platform version + mysql pairings -- Added Travis CI Test Kitchen testing on Fedora 22/23 and removed Fedora 21 -- Updated the platforms used in the specs - ## v6.1.3 (2016-03-14) - Added support for Ubuntu 15.10 @@ -153,7 +65,7 @@ This file is used to list changes made in each version of the mysql cookbook. ## v6.0.21 (2015-04-08) -- Fix to Upstart prestart script when using custom socket +- Fix to Upstart prestart script when using custom socket - Adding --explicit_defaults_for_timestamp mysql_install_db_cmd for - 5.6 and above @@ -274,7 +186,7 @@ This file is used to list changes made in each version of the mysql cookbook. ## v5.5.4 (2014-10-07) -- Adding sensitive flag to execute resources to protect passwords from logs +- Adding sensitive flag to execute resources to protect passwords from logs ## v5.5.3 (2014-09-24) diff --git a/cookbooks/mysql/MAINTAINERS.md b/cookbooks/mysql/MAINTAINERS.md index b3548a4..c6a51ae 100644 --- a/cookbooks/mysql/MAINTAINERS.md +++ b/cookbooks/mysql/MAINTAINERS.md @@ -1,10 +1,13 @@ # Maintainers +This file lists how this cookbook project is maintained. When making changes to the system, this +file tells you who needs to review your patch - you need a simple majority of maintainers +for the relevant subsystems to provide a :+1: on your pull request. Additionally, you need +to not receive a veto from a Lieutenant or the Project Lead. -This file lists how this cookbook project is maintained. When making changes to the system, this file tells you who needs to review your patch - you need a review from an existing maintainer for the cookbook to provide a :+1: on your pull request. Additionally, you need to not receive a veto from a Lieutenant or the Project Lead. - -Check out [How Cookbooks are Maintained](https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/CONTRIBUTING.MD) for details on the process and how to become a maintainer or the project lead. +Check out [How Cookbooks are Maintained](https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/CONTRIBUTING.MD) +for details on the process and how to become a maintainer or the project lead. # Project Maintainer * [Tim Smith](https://github.com/tas50) diff --git a/cookbooks/mysql/README.md b/cookbooks/mysql/README.md index dc046f0..3baa1f6 100644 --- a/cookbooks/mysql/README.md +++ b/cookbooks/mysql/README.md @@ -2,15 +2,16 @@ [![Build Status](https://travis-ci.org/chef-cookbooks/mysql.svg?branch=master)](https://travis-ci.org/chef-cookbooks/mysql) [![Cookbook Version](https://img.shields.io/cookbook/v/mysql.svg)](https://supermarket.chef.io/cookbooks/mysql) -The MySQL Cookbook is a library cookbook that provides resource primitives (LWRPs) for use in recipes. It is designed to be a reference example for creating highly reusable cross-platform cookbooks. +The Mysql Cookbook is a library cookbook that provides resource primitives (LWRPs) for use in recipes. It is designed to be a reference example for creating highly reusable cross-platform cookbooks. ## Scope -This cookbook is concerned with the "MySQL Community Server", particularly those shipped with F/OSS Unix and Linux distributions. It does not address forks or value-added repackaged MySQL distributions like MariaDB or Percona. +This cookbook is concerned with the "MySQL Community Server", particularly those shipped with F/OSS Unix and Linux distributions. It does not address forks or value-added repackaged MySQL distributions like Drizzle, MariaDB, or Percona. ## Requirements -- Chef 12.5 or higher +- Chef 11 or higher +- Ruby 1.9 or higher (preferably from the Chef full-stack installer) - Network accessible package repositories - 'recipe[selinux::disabled]' on RHEL platforms @@ -19,37 +20,42 @@ This cookbook is concerned with the "MySQL Community Server", particularly those The following platforms have been tested with Test Kitchen: ``` -|----------------+-----+-----+-----+-----| -| | 5.1 | 5.5 | 5.6 | 5.7 | -|----------------+-----+-----+-----+-----| -| debian-7 | | X | | | -|----------------+-----+-----+-----+-----| -| debian-8 | | X | | | -|----------------+-----+-----+-----+-----| -| ubuntu-14.04 | | X | X | | -|----------------+-----+-----+-----+-----| -| ubuntu-16.04 | | | | X | -|----------------+-----+-----+-----+-----| -| centos-6 | X | X | X | X | -|----------------+-----+-----+-----+-----| -| centos-7 | | X | X | X | -|----------------+-----+-----+-----+-----| -| fedora | | | X | X | -|----------------+-----+-----+-----+-----| -| openSUSE Leap | | | X | | -|----------------+-----+-----+-----+-----| +|----------------+-----+-----+-----+-----+-----| +| | 5.0 | 5.1 | 5.5 | 5.6 | 5.7 | +|----------------+-----+-----+-----+-----+-----| +| debian-7 | | | X | | | +|----------------+-----+-----+-----+-----+-----| +| ubuntu-12.04 | | | X | | | +|----------------+-----+-----+-----+-----+-----| +| ubuntu-14.04 | | | X | X | | +|----------------+-----+-----+-----+-----+-----| +| ubuntu-15.04 | | | | X | | +|----------------+-----+-----+-----+-----+-----| +| centos-5 | X | X | X | X | X | +|----------------+-----+-----+-----+-----+-----| +| centos-6 | | X | X | X | X | +|----------------+-----+-----+-----+-----+-----| +| centos-7 | | | X | X | X | +|----------------+-----+-----+-----+-----+-----| +| amazon | | | X | X | X | +|----------------+-----+-----+-----+-----+-----| +| fedora-22 | | | X | X | X | +|----------------+-----+-----+-----+-----+-----| +| fedora-23 | | | X | X | X | +|----------------+-----+-----+-----+-----+-----| ``` ## Cookbook Dependencies -There are no hard coupled dependencies. However, there is a loose dependency on `yum-mysql-community` for RHEL/CentOS platforms. As of the 8.0 version of this cookbook, configuration of the package repos is now the responsibility of the user. +- yum-mysql-community +- smf ## Usage Place a dependency on the mysql cookbook in your cookbook's metadata.rb ```ruby -depends 'mysql', '~> 8.0' +depends 'mysql', '~> 6.0' ``` Then, in a recipe: @@ -174,7 +180,7 @@ Please note that when using `notifies` or `subscribes`, the resource to referenc - `:create` - Configures everything but the underlying operating system service. - `:delete` - Removes everything but the package and data_dir. - `:start` - Starts the underlying operating system service -- `:stop`- Stops the underlying operating system service +- `:stop`- Stops the underlying operating system service - `:restart` - Restarts the underlying operating system service - `:reload` - Reloads the underlying operating system service @@ -268,7 +274,7 @@ mysql_client 'default' do end ``` -#### Properties +#### Parameters - `package_name` - An array of packages to be installed. Defaults to a value looked up in an internal map. - `package_version` - Specific versions of the package to install, passed onto the underlying package manager. Defaults to `nil`. @@ -395,16 +401,31 @@ Or to connect over the network, use something like this: connect over the networ These network or socket ssettings can also be put in you $HOME/.my.cnf, if preferred. -### What about MariaDB, Percona, etc. +### What about MariaDB, Percona, Drizzle, WebScaleSQL, etc. MySQL forks are purposefully out of scope for this cookbook. This is mostly to reduce the testing matrix to a manageable size. Cookbooks for these technologies can easily be created by copying and adapting this cookbook. However, there will be differences. Package repository locations, package version names, software major version numbers, supported platform matrices, and the availability of software such as XtraDB and Galera are the main reasons that creating multiple cookbooks to make sense. -## License +## Warnings + +## Hacking / Testing / TODO + +Please refer to the HACKING.md + +## License & Authors + +- Author:: Joshua Timberman ([joshua@chef.io](mailto:joshua@chef.io)) +- Author:: AJ Christensen ([aj@chef.io](mailto:aj@chef.io)) +- Author:: Seth Chisamore ([schisamo@chef.io](mailto:schisamo@chef.io)) +- Author:: Brian Bianco ([brian.bianco@gmail.com](mailto:brian.bianco@gmail.com)) +- Author:: Jesse Howarth ([him@jessehowarth.com](mailto:him@jessehowarth.com)) +- Author:: Andrew Crump ([andrew@kotirisoftware.com](mailto:andrew@kotirisoftware.com)) +- Author:: Christoph Hartmann ([chris@lollyrock.com](mailto:chris@lollyrock.com)) +- Author:: Sean OMeara ([sean@chef.io](mailto:sean@chef.io)) ```text -Copyright:: 2009-2017 Chef Software, Inc +Copyright:: 2009-2014 Chef Software, Inc Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/cookbooks/mysql/libraries/helpers.rb b/cookbooks/mysql/libraries/helpers.rb index 72899fc..8b47559 100644 --- a/cookbooks/mysql/libraries/helpers.rb +++ b/cookbooks/mysql/libraries/helpers.rb @@ -1,118 +1,67 @@ +require 'shellwords' + module MysqlCookbook - module HelpersBase - require 'shellwords' + module Helpers + include Chef::DSL::IncludeRecipe - def el6? - return true if node['platform_family'] == 'rhel' && node['platform_version'].to_i == 6 - false + def base_dir + prefix_dir || '/usr' end - def el7? - return true if node['platform_family'] == 'rhel' && node['platform_version'].to_i == 7 - false + def configure_package_repositories + # we need to enable the yum-mysql-community repository to get packages + return unless %w(rhel fedora).include? node['platform_family'] + case parsed_version + when '5.5' + # Prefer packages from native repos + return if node['platform_family'] == 'rhel' && node['platform_version'].to_i == 5 + return if node['platform_family'] == 'fedora' + include_recipe('yum-mysql-community::mysql55') + when '5.6' + include_recipe('yum-mysql-community::mysql56') + when '5.7' + include_recipe('yum-mysql-community::mysql57') + end end - def wheezy? - return true if node['platform'] == 'debian' && node['platform_version'].to_i == 7 - false - end - - def jessie? - return true if node['platform'] == 'debian' && node['platform_version'].to_i == 8 - false - end - - def trusty? - return true if node['platform'] == 'ubuntu' && node['platform_version'] == '14.04' - return true if node['platform'] == 'linuxmint' && node['platform_version'] =~ /^17\.[0-9]$/ - false - end - - def xenial? - return true if node['platform'] == 'ubuntu' && node['platform_version'] == '16.04' - false + def client_package_name + return new_resource.package_name if new_resource.package_name + client_package end def defaults_file "#{etc_dir}/my.cnf" end - def default_data_dir - return "/var/lib/#{mysql_name}" if node['os'] == 'linux' - return "/opt/local/lib/#{mysql_name}" if node['os'] == 'solaris2' - return "/var/db/#{mysql_name}" if node['os'] == 'freebsd' - end - - def default_error_log + def error_log + return new_resource.error_log if new_resource.error_log "#{log_dir}/error.log" end - def default_pid_file - "#{run_dir}/mysqld.pid" + def etc_dir + return "/opt/mysql#{pkg_ver_string}/etc/#{mysql_name}" if node['platform_family'] == 'omnios' + return "#{prefix_dir}/etc/#{mysql_name}" if node['platform_family'] == 'smartos' + "#{prefix_dir}/etc/#{mysql_name}" end - def default_major_version - # rhelish - return '5.1' if el6? - return '5.6' if el7? - return '5.6' if node['platform'] == 'amazon' - - # debian - return '5.5' if wheezy? - return '5.5' if jessie? - - # ubuntu - return '5.5' if trusty? - return '5.7' if xenial? - - # misc - return '5.6' if node['platform'] == 'freebsd' - return '5.6' if node['platform'] == 'fedora' - return '5.6' if node['platform_family'] == 'suse' + def include_dir + "#{etc_dir}/conf.d" end - def major_from_full(v) - v.split('.').shift(2).join('.') + def lc_messages_dir + end + + def log_dir + return "/var/adm/log/#{mysql_name}" if node['platform_family'] == 'omnios' + "#{prefix_dir}/var/log/#{mysql_name}" end def mysql_name - "mysql-#{instance}" + "mysql-#{new_resource.instance}" end - def default_socket_file - "#{run_dir}/mysqld.sock" - end - - def default_client_package_name - return ['mysql', 'mysql-devel'] if major_version == '5.1' && el6? - return ['mysql55', 'mysql55-devel.x86_64'] if major_version == '5.5' && node['platform'] == 'amazon' - return ['mysql56', 'mysql56-devel.x86_64'] if major_version == '5.6' && node['platform'] == 'amazon' - return ['mysql-client-5.5', 'libmysqlclient-dev'] if major_version == '5.5' && node['platform_family'] == 'debian' - return ['mysql-client-5.6', 'libmysqlclient-dev'] if major_version == '5.6' && node['platform_family'] == 'debian' - return ['mysql-client-5.7', 'libmysqlclient-dev'] if major_version == '5.7' && node['platform_family'] == 'debian' - return 'mysql-community-server-client' if major_version == '5.6' && node['platform_family'] == 'suse' - ['mysql-community-client', 'mysql-community-devel'] - end - - def default_server_package_name - return 'mysql-server' if major_version == '5.1' && el6? - return 'mysql55-server' if major_version == '5.5' && node['platform'] == 'amazon' - return 'mysql56-server' if major_version == '5.6' && node['platform'] == 'amazon' - return 'mysql-server-5.5' if major_version == '5.5' && node['platform_family'] == 'debian' - return 'mysql-server-5.6' if major_version == '5.6' && node['platform_family'] == 'debian' - return 'mysql-server-5.7' if major_version == '5.7' && node['platform_family'] == 'debian' - return 'mysql-community-server' if major_version == '5.6' && node['platform_family'] == 'suse' - 'mysql-community-server' - end - - def socket_dir - File.dirname(socket) - end - - def run_dir - return "#{prefix_dir}/var/run/#{mysql_name}" if node['platform_family'] == 'rhel' - return "/run/#{mysql_name}" if node['platform_family'] == 'debian' - "/var/run/#{mysql_name}" + def pkg_ver_string + parsed_version.delete('.') if node['platform_family'] == 'omnios' end def prefix_dir @@ -123,70 +72,102 @@ module MysqlCookbook def scl_name return unless node['platform_family'] == 'rhel' - return 'mysql51' if version == '5.1' && node['platform_version'].to_i == 5 - return 'mysql55' if version == '5.5' && node['platform_version'].to_i == 5 + return 'mysql51' if parsed_version == '5.1' && node['platform_version'].to_i == 5 + return 'mysql55' if parsed_version == '5.5' && node['platform_version'].to_i == 5 end def scl_package? return unless node['platform_family'] == 'rhel' - return true if version == '5.1' && node['platform_version'].to_i == 5 - return true if version == '5.5' && node['platform_version'].to_i == 5 + return true if parsed_version == '5.1' && node['platform_version'].to_i == 5 + return true if parsed_version == '5.5' && node['platform_version'].to_i == 5 false end - def etc_dir - return "/opt/mysql#{pkg_ver_string}/etc/#{mysql_name}" if node['platform_family'] == 'omnios' - return "#{prefix_dir}/etc/#{mysql_name}" if node['platform_family'] == 'smartos' - "#{prefix_dir}/etc/#{mysql_name}" - end - - def base_dir - prefix_dir || '/usr' - end - def system_service_name return 'mysql51-mysqld' if node['platform_family'] == 'rhel' && scl_name == 'mysql51' return 'mysql55-mysqld' if node['platform_family'] == 'rhel' && scl_name == 'mysql55' return 'mysqld' if node['platform_family'] == 'rhel' return 'mysqld' if node['platform_family'] == 'fedora' - 'mysql' # not one of the above + return 'mysql' if node['platform_family'] == 'debian' + return 'mysql' if node['platform_family'] == 'suse' + return 'mysql' if node['platform_family'] == 'omnios' + return 'mysql' if node['platform_family'] == 'smartos' end def v56plus - return false if version.split('.')[0].to_i < 5 - return false if version.split('.')[1].to_i < 6 + return false if parsed_version.split('.')[0].to_i < 5 + return false if parsed_version.split('.')[1].to_i < 6 true end def v57plus - return false if version.split('.')[0].to_i < 5 - return false if version.split('.')[1].to_i < 7 + return false if parsed_version.split('.')[0].to_i < 5 + return false if parsed_version.split('.')[1].to_i < 7 true end - def default_include_dir - "#{etc_dir}/conf.d" + def password_column_name + return 'authentication_string' if v57plus + 'password' end - def log_dir - return "/var/adm/log/#{mysql_name}" if node['platform_family'] == 'omnios' - "#{prefix_dir}/var/log/#{mysql_name}" + def password_expired + return ", password_expired='N'" if v57plus + '' end - def lc_messages_dir; end + def root_password + if new_resource.initial_root_password == '' + Chef::Log.info('Root password is empty') + return '' + end + Shellwords.escape(new_resource.initial_root_password) + end + + # database and initial records + # initialization commands + + def mysqld_initialize_cmd + cmd = mysqld_bin + cmd << " --defaults-file=#{etc_dir}/my.cnf" + cmd << ' --initialize' + cmd << ' --explicit_defaults_for_timestamp' if v56plus + return "scl enable #{scl_name} \"#{cmd}\"" if scl_package? + cmd + end + + def mysql_install_db_cmd + cmd = mysql_install_db_bin + cmd << " --defaults-file=#{etc_dir}/my.cnf" + cmd << " --datadir=#{parsed_data_dir}" + cmd << ' --explicit_defaults_for_timestamp' if v56plus + return "scl enable #{scl_name} \"#{cmd}\"" if scl_package? + cmd + end + + def record_init + cmd = v56plus ? mysqld_bin : mysqld_safe_bin + cmd << " --defaults-file=#{etc_dir}/my.cnf" + cmd << " --init-file=/tmp/#{mysql_name}/my.sql" + cmd << ' --explicit_defaults_for_timestamp' if v56plus + cmd << ' &' + return "scl enable #{scl_name} \"#{cmd}\"" if scl_package? + cmd + end + + def db_init + return mysqld_initialize_cmd if v57plus + mysql_install_db_cmd + end def init_records_script - # Note: shell-escaping passwords in a SQL file may cause corruption - eg - # mysql will read \& as &, but \% as \%. Just escape bare-minimum \ and ' - sql_escaped_password = root_password.gsub('\\') { '\\\\' }.gsub("'") { '\\\'' } - <<-EOS set -e rm -rf /tmp/#{mysql_name} mkdir /tmp/#{mysql_name} - cat > /tmp/#{mysql_name}/my.sql <<-'EOSQL' -UPDATE mysql.user SET #{password_column_name}=PASSWORD('#{sql_escaped_password}')#{password_expired} WHERE user = 'root'; + cat > /tmp/#{mysql_name}/my.sql <<-EOSQL +UPDATE mysql.user SET #{password_column_name}=PASSWORD('#{root_password}')#{password_expired} WHERE user = 'root'; DELETE FROM mysql.user WHERE USER LIKE ''; DELETE FROM mysql.user WHERE user = 'root' and host NOT IN ('127.0.0.1', 'localhost'); FLUSH PRIVILEGES; @@ -204,27 +185,10 @@ EOSQL EOS end - def password_column_name - return 'authentication_string' if v57plus - 'password' - end - - def root_password - if initial_root_password == '' - Chef::Log.info('Root password is empty') - return '' - end - initial_root_password - end - - def password_expired - return ", password_expired='N'" if v57plus - '' - end - - def db_init - return mysqld_initialize_cmd if v57plus - mysql_install_db_cmd + def mysql_bin + return "#{prefix_dir}/bin/mysql" if node['platform_family'] == 'smartos' + return "#{base_dir}/bin/mysql" if node['platform_family'] == 'omnios' + "#{prefix_dir}/usr/bin/mysql" end def mysql_install_db_bin @@ -233,13 +197,8 @@ EOSQL 'mysql_install_db' end - def mysql_install_db_cmd - cmd = mysql_install_db_bin - cmd << " --defaults-file=#{etc_dir}/my.cnf" - cmd << " --datadir=#{data_dir}" - cmd << ' --explicit_defaults_for_timestamp' if v56plus && !v57plus - return "scl enable #{scl_name} \"#{cmd}\"" if scl_package? - cmd + def mysql_version + new_resource.version end def mysqladmin_bin @@ -257,15 +216,6 @@ EOSQL "#{prefix_dir}/usr/sbin/mysqld" end - def mysqld_initialize_cmd - cmd = mysqld_bin - cmd << " --defaults-file=#{etc_dir}/my.cnf" - cmd << ' --initialize' - cmd << ' --explicit_defaults_for_timestamp' if v56plus - return "scl enable #{scl_name} \"#{cmd}\"" if scl_package? - cmd - end - def mysqld_safe_bin return "#{prefix_dir}/bin/mysqld_safe" if node['platform_family'] == 'smartos' return "#{base_dir}/bin/mysqld_safe" if node['platform_family'] == 'omnios' @@ -273,14 +223,248 @@ EOSQL "#{prefix_dir}/usr/bin/mysqld_safe" end - def record_init - cmd = v56plus ? mysqld_bin : mysqld_safe_bin - cmd << " --defaults-file=#{etc_dir}/my.cnf" - cmd << " --init-file=/tmp/#{mysql_name}/my.sql" - cmd << ' --explicit_defaults_for_timestamp' if v56plus - cmd << ' &' - return "scl enable #{scl_name} \"#{cmd}\"" if scl_package? - cmd + def pid_file + return new_resource.pid_file if new_resource.pid_file + "#{run_dir}/mysqld.pid" + end + + def run_dir + return "#{prefix_dir}/var/run/#{mysql_name}" if node['platform_family'] == 'rhel' + return "/run/#{mysql_name}" if node['platform_family'] == 'debian' + "/var/run/#{mysql_name}" + end + + def sensitive_supported? + Gem::Version.new(Chef::VERSION) >= Gem::Version.new('11.14.0') + end + + def socket_file + return new_resource.socket if new_resource.socket + "#{run_dir}/mysqld.sock" + end + + def socket_dir + return File.dirname(new_resource.socket) if new_resource.socket + run_dir + end + + def tmp_dir + return new_resource.tmp_dir if new_resource.tmp_dir + '/tmp' + end + + ####### + # FIXME: There is a LOT of duplication here.. + # There has to be a less gnarly way to look up this information. Refactor for great good! + ####### + class Pkginfo + def self.pkginfo + # Autovivification is Perl. + @pkginfo = Chef::Node.new + + @pkginfo.set['debian']['10.04']['5.1']['client_package'] = %w(mysql-client-5.1 libmysqlclient-dev) + @pkginfo.set['debian']['10.04']['5.1']['server_package'] = 'mysql-server-5.1' + @pkginfo.set['debian']['12.04']['5.5']['client_package'] = %w(mysql-client-5.5 libmysqlclient-dev) + @pkginfo.set['debian']['12.04']['5.5']['server_package'] = 'mysql-server-5.5' + @pkginfo.set['debian']['13.04']['5.5']['client_package'] = %w(mysql-client-5.5 libmysqlclient-dev) + @pkginfo.set['debian']['13.04']['5.5']['server_package'] = 'mysql-server-5.5' + @pkginfo.set['debian']['13.10']['5.5']['client_package'] = %w(mysql-client-5.5 libmysqlclient-dev) + @pkginfo.set['debian']['13.10']['5.5']['server_package'] = 'mysql-server-5.5' + @pkginfo.set['debian']['14.04']['5.5']['client_package'] = %w(mysql-client-5.5 libmysqlclient-dev) + @pkginfo.set['debian']['14.04']['5.5']['server_package'] = 'mysql-server-5.5' + @pkginfo.set['debian']['14.04']['5.6']['client_package'] = %w(mysql-client-5.6 libmysqlclient-dev) + @pkginfo.set['debian']['14.04']['5.6']['server_package'] = 'mysql-server-5.6' + @pkginfo.set['debian']['14.10']['5.5']['client_package'] = %w(mysql-client-5.5 libmysqlclient-dev) + @pkginfo.set['debian']['14.10']['5.5']['server_package'] = 'mysql-server-5.5' + @pkginfo.set['debian']['14.10']['5.6']['client_package'] = %w(mysql-client-5.6 libmysqlclient-dev) + @pkginfo.set['debian']['14.10']['5.6']['server_package'] = 'mysql-server-5.6' + @pkginfo.set['debian']['15.04']['5.6']['client_package'] = %w(mysql-client-5.6 libmysqlclient-dev) + @pkginfo.set['debian']['15.04']['5.6']['server_package'] = 'mysql-server-5.6' + @pkginfo.set['debian']['15.10']['5.6']['client_package'] = %w(mysql-client-5.6 libmysqlclient-dev) + @pkginfo.set['debian']['15.10']['5.6']['server_package'] = 'mysql-server-5.6' + @pkginfo.set['debian']['6']['5.1']['client_package'] = %w(mysql-client libmysqlclient-dev) + @pkginfo.set['debian']['6']['5.1']['server_package'] = 'mysql-server-5.1' + @pkginfo.set['debian']['7']['5.5']['client_package'] = %w(mysql-client libmysqlclient-dev) + @pkginfo.set['debian']['7']['5.5']['server_package'] = 'mysql-server-5.5' + @pkginfo.set['debian']['7']['5.6']['client_package'] = %w(mysql-client libmysqlclient-dev) # apt-repo from dotdeb + @pkginfo.set['debian']['7']['5.6']['server_package'] = 'mysql-server-5.6' + @pkginfo.set['debian']['7']['5.7']['client_package'] = %w(mysql-client libmysqlclient-dev) # apt-repo from dotdeb + @pkginfo.set['debian']['7']['5.7']['server_package'] = 'mysql-server-5.7' + @pkginfo.set['debian']['8']['5.5']['client_package'] = %w(mysql-client libmysqlclient-dev) + @pkginfo.set['debian']['8']['5.5']['server_package'] = 'mysql-server-5.5' + @pkginfo.set['fedora']['20']['5.5']['client_package'] = %w(community-mysql community-mysql-devel) + @pkginfo.set['fedora']['20']['5.5']['server_package'] = 'community-mysql-server' + @pkginfo.set['fedora']['20']['5.6']['client_package'] = %w(mysql-community-client mysql-community-devel) + @pkginfo.set['fedora']['20']['5.6']['server_package'] = 'mysql-community-server' + @pkginfo.set['fedora']['20']['5.7']['client_package'] = %w(mysql-community-client mysql-community-devel) + @pkginfo.set['fedora']['20']['5.7']['server_package'] = 'mysql-community-server' + @pkginfo.set['fedora']['21']['5.6']['client_package'] = %w(mysql-community-client mysql-community-devel) + @pkginfo.set['fedora']['21']['5.6']['server_package'] = 'mysql-community-server' + @pkginfo.set['fedora']['21']['5.7']['client_package'] = %w(mysql-community-client mysql-community-devel) + @pkginfo.set['fedora']['21']['5.7']['server_package'] = 'mysql-community-server' + @pkginfo.set['fedora']['22']['5.6']['client_package'] = %w(mysql-community-client mysql-community-devel) + @pkginfo.set['fedora']['22']['5.6']['server_package'] = 'mysql-community-server' + @pkginfo.set['fedora']['22']['5.7']['client_package'] = %w(mysql-community-client mysql-community-devel) + @pkginfo.set['fedora']['22']['5.7']['server_package'] = 'mysql-community-server' + @pkginfo.set['freebsd']['10']['5.5']['client_package'] = %w(mysql55-client) + @pkginfo.set['freebsd']['10']['5.5']['server_package'] = 'mysql55-server' + @pkginfo.set['freebsd']['9']['5.5']['client_package'] = %w(mysql55-client) + @pkginfo.set['freebsd']['9']['5.5']['server_package'] = 'mysql55-server' + @pkginfo.set['omnios']['151006']['5.5']['client_package'] = %w(database/mysql-55/library) + @pkginfo.set['omnios']['151006']['5.5']['server_package'] = 'database/mysql-55' + @pkginfo.set['omnios']['151006']['5.6']['client_package'] = %w(database/mysql-56) + @pkginfo.set['omnios']['151006']['5.6']['server_package'] = 'database/mysql-56' + @pkginfo.set['rhel']['2014.09']['5.1']['server_package'] = %w(mysql51 mysql51-devel) + @pkginfo.set['rhel']['2014.09']['5.1']['server_package'] = 'mysql51-server' + @pkginfo.set['rhel']['2014.09']['5.5']['client_package'] = %w(mysql-community-client mysql-community-devel) + @pkginfo.set['rhel']['2014.09']['5.5']['server_package'] = 'mysql-community-server' + @pkginfo.set['rhel']['2014.09']['5.6']['client_package'] = %w(mysql-community-client mysql-community-devel) + @pkginfo.set['rhel']['2014.09']['5.6']['server_package'] = 'mysql-community-server' + @pkginfo.set['rhel']['2014.09']['5.7']['client_package'] = %w(mysql-community-client mysql-community-devel) + @pkginfo.set['rhel']['2014.09']['5.7']['server_package'] = 'mysql-community-server' + @pkginfo.set['rhel']['2015.03']['5.1']['server_package'] = %w(mysql51 mysql51-devel) + @pkginfo.set['rhel']['2015.03']['5.1']['server_package'] = 'mysql51-server' + @pkginfo.set['rhel']['2015.03']['5.5']['client_package'] = %w(mysql-community-client mysql-community-devel) + @pkginfo.set['rhel']['2015.03']['5.5']['server_package'] = 'mysql-community-server' + @pkginfo.set['rhel']['2015.03']['5.6']['client_package'] = %w(mysql-community-client mysql-community-devel) + @pkginfo.set['rhel']['2015.03']['5.6']['server_package'] = 'mysql-community-server' + @pkginfo.set['rhel']['2015.03']['5.7']['client_package'] = %w(mysql-community-client mysql-community-devel) + @pkginfo.set['rhel']['2015.03']['5.7']['server_package'] = 'mysql-community-server' + @pkginfo.set['rhel']['2015.09']['5.1']['server_package'] = %w(mysql51 mysql51-devel) + @pkginfo.set['rhel']['2015.09']['5.1']['server_package'] = 'mysql51-server' + @pkginfo.set['rhel']['2015.09']['5.5']['client_package'] = %w(mysql-community-client mysql-community-devel) + @pkginfo.set['rhel']['2015.09']['5.5']['server_package'] = 'mysql-community-server' + @pkginfo.set['rhel']['2015.09']['5.6']['client_package'] = %w(mysql-community-client mysql-community-devel) + @pkginfo.set['rhel']['2015.09']['5.6']['server_package'] = 'mysql-community-server' + @pkginfo.set['rhel']['2015.09']['5.7']['client_package'] = %w(mysql-community-client mysql-community-devel) + @pkginfo.set['rhel']['2015.09']['5.7']['server_package'] = 'mysql-community-server' + @pkginfo.set['rhel']['2016.03']['5.1']['server_package'] = %w(mysql51 mysql51-devel) + @pkginfo.set['rhel']['2016.03']['5.1']['server_package'] = 'mysql51-server' + @pkginfo.set['rhel']['2016.03']['5.5']['client_package'] = %w(mysql-community-client mysql-community-devel) + @pkginfo.set['rhel']['2016.03']['5.5']['server_package'] = 'mysql-community-server' + @pkginfo.set['rhel']['2016.03']['5.6']['client_package'] = %w(mysql-community-client mysql-community-devel) + @pkginfo.set['rhel']['2016.03']['5.6']['server_package'] = 'mysql-community-server' + @pkginfo.set['rhel']['2016.03']['5.7']['client_package'] = %w(mysql-community-client mysql-community-devel) + @pkginfo.set['rhel']['2016.03']['5.7']['server_package'] = 'mysql-community-server' + @pkginfo.set['rhel']['5']['5.0']['client_package'] = %w(mysql mysql-devel) + @pkginfo.set['rhel']['5']['5.0']['server_package'] = 'mysql-server' + @pkginfo.set['rhel']['5']['5.1']['client_package'] = %w(mysql51-mysql) + @pkginfo.set['rhel']['5']['5.1']['server_package'] = 'mysql51-mysql-server' + @pkginfo.set['rhel']['5']['5.5']['client_package'] = %w(mysql55-mysql mysql55-mysql-devel) + @pkginfo.set['rhel']['5']['5.5']['server_package'] = 'mysql55-mysql-server' + @pkginfo.set['rhel']['5']['5.6']['client_package'] = %w(mysql-community-client mysql-community-devel) + @pkginfo.set['rhel']['5']['5.6']['server_package'] = 'mysql-community-server' + @pkginfo.set['rhel']['5']['5.7']['client_package'] = %w(mysql-community-client mysql-community-devel) + @pkginfo.set['rhel']['5']['5.7']['server_package'] = 'mysql-community-server' + @pkginfo.set['rhel']['6']['5.1']['client_package'] = %w(mysql mysql-devel) + @pkginfo.set['rhel']['6']['5.1']['server_package'] = 'mysql-server' + @pkginfo.set['rhel']['6']['5.5']['client_package'] = %w(mysql-community-client mysql-community-devel) + @pkginfo.set['rhel']['6']['5.5']['server_package'] = 'mysql-community-server' + @pkginfo.set['rhel']['6']['5.6']['client_package'] = %w(mysql-community-client mysql-community-devel) + @pkginfo.set['rhel']['6']['5.6']['server_package'] = 'mysql-community-server' + @pkginfo.set['rhel']['6']['5.7']['client_package'] = %w(mysql-community-client mysql-community-devel) + @pkginfo.set['rhel']['6']['5.7']['server_package'] = 'mysql-community-server' + @pkginfo.set['rhel']['7']['5.5']['client_package'] = %w(mysql-community-client mysql-community-devel) + @pkginfo.set['rhel']['7']['5.5']['server_package'] = 'mysql-community-server' + @pkginfo.set['rhel']['7']['5.6']['client_package'] = %w(mysql-community-client mysql-community-devel) + @pkginfo.set['rhel']['7']['5.6']['server_package'] = 'mysql-community-server' + @pkginfo.set['rhel']['7']['5.7']['client_package'] = %w(mysql-community-client mysql-community-devel) + @pkginfo.set['rhel']['7']['5.7']['server_package'] = 'mysql-community-server' + @pkginfo.set['smartos']['5.11']['5.5']['client_package'] = %w(mysql-client) + @pkginfo.set['smartos']['5.11']['5.5']['server_package'] = 'mysql-server' + @pkginfo.set['smartos']['5.11']['5.6']['client_package'] = %w(mysql-client) + @pkginfo.set['smartos']['5.11']['5.6']['server_package'] = 'mysql-server' + @pkginfo.set['suse']['11.3']['5.5']['client_package'] = %w(mysql-client) + @pkginfo.set['suse']['11.3']['5.5']['server_package'] = 'mysql' + @pkginfo.set['suse']['12.0']['5.5']['client_package'] = %w(mysql-client) + @pkginfo.set['suse']['12.0']['5.5']['server_package'] = 'mysql' + + @pkginfo + end + end + + def package_name_for(platform, platform_family, platform_version, version, type) + keyname = keyname_for(platform, platform_family, platform_version) + info = Pkginfo.pkginfo[platform_family.to_sym][keyname] + type_label = type.to_s.gsub('_package', '').capitalize + unless info[version] + # Show availabe versions if the requested is not available on the current platform + Chef::Log.error("Unsupported Version: You requested to install a Mysql #{type_label} version that is not supported by your platform") + Chef::Log.error("Platform: #{platform_family} #{platform_version} - Request Mysql #{type_label} version: #{version}") + Chef::Log.error("Availabe versions for your platform are: #{info.map { |k, _v| k }.join(' - ')}") + raise "Unsupported Mysql #{type_label} Version" + end + info[version][type] + end + + def keyname_for(platform, platform_family, platform_version) + return platform_version if platform_family == 'debian' && platform == 'ubuntu' + return platform_version if platform_family == 'fedora' + return platform_version if platform_family == 'omnios' + return platform_version if platform_family == 'rhel' && platform == 'amazon' + return platform_version if platform_family == 'smartos' + return platform_version if platform_family == 'suse' + return platform_version.to_i.to_s if platform_family == 'debian' + return platform_version.to_i.to_s if platform_family == 'rhel' + return platform_version.to_s if platform_family == 'debian' && platform_version =~ /sid$/ + return platform_version.to_s if platform_family == 'freebsd' + end + + def parsed_data_dir + return new_resource.data_dir if new_resource.data_dir + return "/opt/local/lib/#{mysql_name}" if node['os'] == 'solaris2' + return "/var/lib/#{mysql_name}" if node['os'] == 'linux' + return "/var/db/#{mysql_name}" if node['os'] == 'freebsd' + end + + def client_package + package_name_for( + node['platform'], + node['platform_family'], + node['platform_version'], + parsed_version, + :client_package + ) + end + + def server_package + package_name_for( + node['platform'], + node['platform_family'], + node['platform_version'], + parsed_version, + :server_package + ) + end + + def server_package_name + return new_resource.package_name if new_resource.package_name + server_package + end + + def parsed_version + return new_resource.version if new_resource.version + return '5.0' if node['platform_family'] == 'rhel' && node['platform_version'].to_i == 5 + return '5.1' if node['platform_family'] == 'debian' && node['platform_version'] == '10.04' + return '5.1' if node['platform_family'] == 'debian' && node['platform_version'].to_i == 6 + return '5.1' if node['platform_family'] == 'rhel' && node['platform_version'].to_i == 6 + return '5.5' if node['platform_family'] == 'debian' && node['platform_version'] == '12.04' + return '5.5' if node['platform_family'] == 'debian' && node['platform_version'] == '13.04' + return '5.5' if node['platform_family'] == 'debian' && node['platform_version'] == '13.10' + return '5.5' if node['platform_family'] == 'debian' && node['platform_version'] == '14.04' + return '5.5' if node['platform_family'] == 'debian' && node['platform_version'] == '14.10' + return '5.5' if node['platform_family'] == 'debian' && node['platform_version'].to_i == 7 + return '5.5' if node['platform_family'] == 'debian' && node['platform_version'].to_i == 8 + return '5.5' if node['platform_family'] == 'freebsd' + return '5.5' if node['platform_family'] == 'omnios' + return '5.5' if node['platform_family'] == 'rhel' && node['platform_version'].to_i == 2014 + return '5.5' if node['platform_family'] == 'rhel' && node['platform_version'].to_i == 2015 + return '5.5' if node['platform_family'] == 'rhel' && node['platform_version'].to_i == 7 + return '5.5' if node['platform_family'] == 'smartos' + return '5.5' if node['platform_family'] == 'suse' + return '5.6' if node['platform_family'] == 'fedora' + return '5.6' if node['platform_family'] == 'debian' && node['platform_version'] == '15.04' + return '5.6' if node['platform_family'] == 'debian' && node['platform_version'] == '15.10' end end end diff --git a/cookbooks/mysql/libraries/matchers.rb b/cookbooks/mysql/libraries/matchers.rb index adf5e73..373e3cb 100644 --- a/cookbooks/mysql/libraries/matchers.rb +++ b/cookbooks/mysql/libraries/matchers.rb @@ -1,40 +1,18 @@ if defined?(ChefSpec) - ChefSpec.define_matcher :mysql_config - ChefSpec.define_matcher :mysql_service - ChefSpec.define_matcher :mysql_client - - # mysql_client_client_installation_package - def install_mysql_client_installation_package(resource_name) - ChefSpec::Matchers::ResourceMatcher.new(:mysql_client_installation_package, :create, resource_name) + if ChefSpec.respond_to?(:define_matcher) + # ChefSpec >= 4.1 + ChefSpec.define_matcher :mysql_config + ChefSpec.define_matcher :mysql_service + ChefSpec.define_matcher :mysql_client + elsif defined?(ChefSpec::Runner) && + ChefSpec::Runner.respond_to?(:define_runner_method) + # ChefSpec < 4.1 + ChefSpec::Runner.define_runner_method :mysql_config + ChefSpec::Runner.define_runner_method :mysql_service + ChefSpec::Runner.define_runner_method :mysql_client end - def remove_mysql_client_installation_package(resource_name) - ChefSpec::Matchers::ResourceMatcher.new(:mysql_client_installation_package, :remove, resource_name) - end - - # mysql_server_server_installation_package - def install_mysql_server_installation_package(resource_name) - ChefSpec::Matchers::ResourceMatcher.new(:mysql_server_installation_package, :install, resource_name) - end - - def remove_mysql_server_installation_package(resource_name) - ChefSpec::Matchers::ResourceMatcher.new(:mysql_server_installation_package, :remove, resource_name) - end - - ##### - # old - ##### - - # client - def create_mysql_client(resource_name) - ChefSpec::Matchers::ResourceMatcher.new(:mysql_client, :create, resource_name) - end - - def delete_mysql_client(resource_name) - ChefSpec::Matchers::ResourceMatcher.new(:mysql_client, :delete, resource_name) - end - - # mysql_config + # config def create_mysql_config(resource_name) ChefSpec::Matchers::ResourceMatcher.new(:mysql_config, :create, resource_name) end @@ -68,4 +46,12 @@ if defined?(ChefSpec) ChefSpec::Matchers::ResourceMatcher.new(:mysql_service, :reload, resource_name) end + # client + def create_mysql_client(resource_name) + ChefSpec::Matchers::ResourceMatcher.new(:mysql_client, :create, resource_name) + end + + def delete_mysql_client(resource_name) + ChefSpec::Matchers::ResourceMatcher.new(:mysql_client, :delete, resource_name) + end end diff --git a/cookbooks/mysql/libraries/mysql_base.rb b/cookbooks/mysql/libraries/mysql_base.rb deleted file mode 100644 index b04a129..0000000 --- a/cookbooks/mysql/libraries/mysql_base.rb +++ /dev/null @@ -1,30 +0,0 @@ -module MysqlCookbook - class MysqlBase < Chef::Resource - require_relative 'helpers' - - # All resources are composites - def whyrun_supported? - true - end - - ################ - # Type Constants - ################ - - Boolean = property_type( - is: [true, false], - default: false - ) unless defined?(Boolean) - - ################### - # Common Properties - ################### - property :run_group, String, default: 'mysql', desired_state: false - property :run_user, String, default: 'mysql', desired_state: false - property :version, String, default: lazy { default_major_version }, desired_state: false - property :include_dir, String, default: lazy { default_include_dir }, desired_state: false - property :major_version, String, default: lazy { major_from_full(version) }, desired_state: false - - declare_action_class - end -end diff --git a/cookbooks/mysql/libraries/mysql_client_installation_package.rb b/cookbooks/mysql/libraries/mysql_client_installation_package.rb deleted file mode 100644 index 1e1d946..0000000 --- a/cookbooks/mysql/libraries/mysql_client_installation_package.rb +++ /dev/null @@ -1,31 +0,0 @@ -module MysqlCookbook - class MysqlClientInstallationPackage < MysqlBase - # helper methods - require_relative 'helpers' - include MysqlCookbook::HelpersBase - - # Resource properties - resource_name :mysql_client_installation_package - provides :mysql_client_installation, os: 'linux' - provides :mysql_client, os: 'linux' - - property :package_name, [String, Array], default: lazy { default_client_package_name }, desired_state: false - property :package_options, [String, nil], desired_state: false - property :package_version, [String, nil], default: nil, desired_state: false - - # Actions - action :create do - package package_name do - version package_version if package_version - options package_options if package_options - action :install - end - end - - action :delete do - package package_name do - action :remove - end - end - end -end diff --git a/cookbooks/mysql/libraries/mysql_config.rb b/cookbooks/mysql/libraries/mysql_config.rb deleted file mode 100644 index be5eee0..0000000 --- a/cookbooks/mysql/libraries/mysql_config.rb +++ /dev/null @@ -1,56 +0,0 @@ -module MysqlCookbook - class MysqlConfig < MysqlBase - resource_name :mysql_config - - property :config_name, String, name_property: true, desired_state: false - property :cookbook, String, desired_state: false - property :group, String, default: 'mysql', desired_state: false - property :instance, String, default: 'default', desired_state: false - property :owner, String, default: 'mysql', desired_state: false - property :source, String, desired_state: false - property :variables, [Hash], desired_state: false - property :version, String, default: lazy { default_major_version }, desired_state: false - - require_relative 'helpers' - include MysqlCookbook::HelpersBase - - provides :mysql_config - - action :create do - # hax because group property - g = Chef::Resource::Group.new(new_resource.group, run_context) - g.system true if name == 'mysql' - resource_collection.insert g - - user owner do - gid owner - system true if name == 'mysql' - action :create - end - - directory include_dir do - owner new_resource.owner - group new_resource.group - mode '0750' - recursive true - action :create - end - - template "#{include_dir}/#{config_name}.cnf" do - owner new_resource.owner - group new_resource.group - mode '0640' - variables(new_resource.variables) - source new_resource.source - cookbook new_resource.cookbook - action :create - end - end - - action :delete do - file "#{include_dir}/#{config_name}.cnf" do - action :delete - end - end - end -end diff --git a/cookbooks/mysql/libraries/mysql_server_installation_package.rb b/cookbooks/mysql/libraries/mysql_server_installation_package.rb deleted file mode 100644 index 385e202..0000000 --- a/cookbooks/mysql/libraries/mysql_server_installation_package.rb +++ /dev/null @@ -1,42 +0,0 @@ -module MysqlCookbook - class MysqlServerInstallationPackage < MysqlBase - # Resource properties - resource_name :mysql_server_installation_package - provides :mysql_server_installation, os: 'linux' - - property :package_name, String, default: lazy { default_server_package_name }, desired_state: false - property :package_options, [String, nil], desired_state: false - property :package_version, [String, nil], default: nil, desired_state: false - - # helper methods - require_relative 'helpers' - include MysqlCookbook::HelpersBase - - # Actions - action :install do - package package_name do - version package_version if package_version - options package_options if package_options - notifies :install, 'package[perl-Sys-Hostname-Long]', :immediately if platform_family?('suse') - notifies :run, 'execute[Initial DB setup script]', :immediately if platform_family?('suse') - action :install - end - - package 'perl-Sys-Hostname-Long' do - action :nothing - end - - execute 'Initial DB setup script' do - environment 'INSTANCE' => new_resource.name - command '/usr/lib/mysql/mysql-systemd-helper install' - action :nothing - end - end - - action :delete do - package package_name do - action :remove - end - end - end -end diff --git a/cookbooks/mysql/libraries/mysql_service.rb b/cookbooks/mysql/libraries/mysql_service.rb deleted file mode 100644 index 80fb7c3..0000000 --- a/cookbooks/mysql/libraries/mysql_service.rb +++ /dev/null @@ -1,105 +0,0 @@ -module MysqlCookbook - require_relative 'mysql_service_base' - class MysqlService < MysqlServiceBase - resource_name :mysql_service - - # installation type and service_manager - property :install_method, %w(package auto), default: 'auto', desired_state: false - property :service_manager, %w(sysvinit upstart systemd auto), default: 'auto', desired_state: false - - # mysql_server_installation - property :version, String, default: lazy { default_major_version }, desired_state: false - property :major_version, String, default: lazy { major_from_full(version) }, desired_state: false - property :package_name, String, default: lazy { default_package_name }, desired_state: false - property :package_options, [String, nil], desired_state: false - property :package_version, [String, nil], default: nil, desired_state: false - - ################ - # Helper Methods - ################ - - def copy_properties_to(to, *properties) - properties = self.class.properties.keys if properties.empty? - properties.each do |p| - # If the property is set on from, and exists on to, set the - # property on to - if to.class.properties.include?(p) && property_is_set?(p) - to.send(p, send(p)) - end - end - end - - action_class.class_eval do - def installation(&block) - case install_method - when 'auto' - install = mysql_server_installation(name, &block) - when 'package' - install = mysql_server_installation_package(name, &block) - when 'none' - Chef::Log.info('Skipping MySQL installation. Assuming it was handled previously.') - return - end - copy_properties_to(install) - install - end - - def svc_manager(&block) - case service_manager - when 'auto' - svc = mysql_service_manager(name, &block) - when 'sysvinit' - svc = mysql_service_manager_sysvinit(name, &block) - when 'upstart' - svc = mysql_service_manager_upstart(name, &block) - when 'systemd' - svc = mysql_service_manager_systemd(name, &block) - end - copy_properties_to(svc) - svc - end - end - - ######### - # Actions - ######### - - action :create do - installation do - action :install - end - - svc_manager do - action :create - end - end - - action :start do - svc_manager do - action :start - end - end - - action :delete do - svc_manager do - action :delete - end - - installation do - action :delete - end - end - - action :restart do - svc_manager do - action :restart - end - end - - action :stop do - svc_manager do - action :stop - end - end - end -end diff --git a/cookbooks/mysql/libraries/mysql_service_base.rb b/cookbooks/mysql/libraries/mysql_service_base.rb deleted file mode 100644 index 01f26c7..0000000 --- a/cookbooks/mysql/libraries/mysql_service_base.rb +++ /dev/null @@ -1,203 +0,0 @@ -module MysqlCookbook - class MysqlServiceBase < MysqlBase - property :bind_address, String, desired_state: false - property :charset, String, default: 'utf8', desired_state: false - property :data_dir, String, default: lazy { default_data_dir }, desired_state: false - property :error_log, String, default: lazy { default_error_log }, desired_state: false - property :initial_root_password, String, default: 'ilikerandompasswords', desired_state: false - property :instance, String, name_property: true, desired_state: false - property :mysqld_options, Hash, default: {}, desired_state: false - property :pid_file, String, default: lazy { default_pid_file }, desired_state: false - property :port, [String, Integer], default: '3306', desired_state: false - property :socket, String, default: lazy { default_socket_file }, desired_state: false - property :tmp_dir, String, desired_state: false - - alias socket_file socket - - require_relative 'helpers' - include MysqlCookbook::HelpersBase - - # action class methods are available within the actions and work as if the coded - # was inline the action. No messing with classes or passing in the new_resource - declare_action_class.class_eval do - def create_system_user - group 'mysql' do - action :create - end - - user 'mysql' do - gid 'mysql' - action :create - end - end - - def create_config - # require 'pry' ; binding.pry - - # Yak shaving secion. Account for random errata. - # - # Turns out that mysqld is hard coded to try and read - # /etc/mysql/my.cnf, and its presence causes problems when - # setting up multiple services. - file "#{prefix_dir}/etc/mysql/my.cnf" do - action :delete - end - - file "#{prefix_dir}/etc/my.cnf" do - action :delete - end - - # mysql_install_db is broken on 5.6.13 - link "#{prefix_dir}/usr/share/my-default.cnf" do - to "#{etc_dir}/my.cnf" - not_if { ::File.exist? "#{prefix_dir}/usr/share/my-default.cnf" } # FIXME: Chef bug? - action :create - end - - # Support directories - directory etc_dir do - owner run_user - group run_group - mode '0750' - recursive true - action :create - end - - directory include_dir do - owner run_user - group run_group - mode '0750' - recursive true - action :create - end - - directory run_dir do - owner run_user - group run_group - mode '0755' - recursive true - action :create - end - - directory log_dir do - owner run_user - group run_group - mode '0750' - recursive true - action :create - end - - directory data_dir do - owner run_user - group run_group - mode '0750' - recursive true - action :create - end - - # Main configuration file - template "#{etc_dir}/my.cnf" do - source 'my.cnf.erb' - cookbook 'mysql' - owner run_user - group run_group - mode '0600' - variables(config: new_resource) - action :create - end - end - - def initialize_database - # initialize database and create initial records - bash "#{name} initial records" do - code init_records_script - umask '022' - returns [0, 1, 2] # facepalm - not_if "/usr/bin/test -f #{data_dir}/mysql/user.frm" - action :run - end - end - - def delete_support_directories - # Stop the service before removing support directories - delete_stop_service - - directory etc_dir do - recursive true - action :delete - end - - directory run_dir do - recursive true - action :delete - end - - directory log_dir do - recursive true - action :delete - end - end - - # - # Platform specific bits - # - def configure_apparmor - # Do not add these resource if inside a container - # Only valid on Ubuntu - return if ::File.exist?('/.dockerenv') || ::File.exist?('/.dockerinit') || node['platform'] != 'ubuntu' - - # Apparmor - package 'apparmor' do - action :install - end - - directory '/etc/apparmor.d/local/mysql' do - owner 'root' - group 'root' - mode '0755' - recursive true - action :create - end - - template '/etc/apparmor.d/local/usr.sbin.mysqld' do - cookbook 'mysql' - source 'apparmor/usr.sbin.mysqld-local.erb' - owner 'root' - group 'root' - mode '0644' - action :create - notifies :restart, "service[#{instance} apparmor]", :immediately - end - - template '/etc/apparmor.d/usr.sbin.mysqld' do - cookbook 'mysql' - source 'apparmor/usr.sbin.mysqld.erb' - owner 'root' - group 'root' - mode '0644' - action :create - notifies :restart, "service[#{instance} apparmor]", :immediately - end - - template "/etc/apparmor.d/local/mysql/#{instance}" do - cookbook 'mysql' - source 'apparmor/usr.sbin.mysqld-instance.erb' - owner 'root' - group 'root' - mode '0644' - variables( - config: new_resource, - mysql_name: mysql_name - ) - action :create - notifies :restart, "service[#{instance} apparmor]", :immediately - end - - service "#{instance} apparmor" do - service_name 'apparmor' - action :nothing - end - end - end - end -end diff --git a/cookbooks/mysql/libraries/mysql_service_manager_systemd.rb b/cookbooks/mysql/libraries/mysql_service_manager_systemd.rb deleted file mode 100644 index e18fe74..0000000 --- a/cookbooks/mysql/libraries/mysql_service_manager_systemd.rb +++ /dev/null @@ -1,142 +0,0 @@ -module MysqlCookbook - class MysqlServiceManagerSystemd < MysqlServiceBase - resource_name :mysql_service_manager_systemd - - provides :mysql_service_manager, os: 'linux' do |_node| - Chef::Platform::ServiceHelpers.service_resource_providers.include?(:systemd) - end - - action :create do - # from base - create_system_user - stop_system_service - create_config - configure_apparmor - initialize_database - end - - action :start do - # Needed for Debian / Ubuntu - directory '/usr/libexec' do - owner 'root' - group 'root' - mode '0755' - action :create - end - - # this script is called by the main systemd unit file, and - # spins around until the service is actually up and running. - template "/usr/libexec/#{mysql_name}-wait-ready" do - path "/usr/libexec/#{mysql_name}-wait-ready" - source 'systemd/mysqld-wait-ready.erb' - owner 'root' - group 'root' - mode '0755' - variables(socket_file: socket_file) - cookbook 'mysql' - action :create - end - - # this is the main systemd unit file - template "/etc/systemd/system/#{mysql_name}.service" do - path "/etc/systemd/system/#{mysql_name}.service" - source 'systemd/mysqld.service.erb' - owner 'root' - group 'root' - mode '0644' - variables( - config: new_resource, - etc_dir: etc_dir, - base_dir: base_dir, - mysqld_bin: mysqld_bin - ) - cookbook 'mysql' - notifies :run, "execute[#{instance} systemctl daemon-reload]", :immediately - action :create - end - - # avoid 'Unit file changed on disk' warning - execute "#{instance} systemctl daemon-reload" do - command '/bin/systemctl daemon-reload' - action :nothing - end - - # tmpfiles.d config so the service survives reboot - template "/usr/lib/tmpfiles.d/#{mysql_name}.conf" do - path "/usr/lib/tmpfiles.d/#{mysql_name}.conf" - source 'tmpfiles.d.conf.erb' - owner 'root' - group 'root' - mode '0644' - variables( - run_dir: run_dir, - run_user: run_user, - run_group: run_group - ) - cookbook 'mysql' - action :create - end - - # service management resource - service mysql_name.to_s do - service_name mysql_name - provider Chef::Provider::Service::Systemd - supports restart: true, status: true - action [:enable, :start] - end - end - - action :stop do - # service management resource - service mysql_name.to_s do - service_name mysql_name - provider Chef::Provider::Service::Systemd - supports status: true - action [:disable, :stop] - only_if { ::File.exist?("/usr/lib/systemd/system/#{mysql_name}.service") } - end - end - - action :restart do - # service management resource - service mysql_name.to_s do - service_name mysql_name - provider Chef::Provider::Service::Systemd - supports restart: true - action :restart - end - end - - action :reload do - # service management resource - service mysql_name.to_s do - service_name mysql_name - provider Chef::Provider::Service::Systemd - action :reload - end - end - - declare_action_class.class_eval do - def stop_system_service - # service management resource - service 'mysql' do - service_name system_service_name - provider Chef::Provider::Service::Systemd - supports status: true - action [:stop, :disable] - end - end - - def delete_stop_service - # service management resource - service mysql_name.to_s do - service_name mysql_name - provider Chef::Provider::Service::Systemd - supports status: true - action [:disable, :stop] - only_if { ::File.exist?("/usr/lib/systemd/system/#{mysql_name}.service") } - end - end - end - end -end diff --git a/cookbooks/mysql/libraries/mysql_service_manager_sysvinit.rb b/cookbooks/mysql/libraries/mysql_service_manager_sysvinit.rb deleted file mode 100644 index 1b76064..0000000 --- a/cookbooks/mysql/libraries/mysql_service_manager_sysvinit.rb +++ /dev/null @@ -1,79 +0,0 @@ -module MysqlCookbook - class MysqlServiceManagerSysvinit < MysqlServiceBase - resource_name :mysql_service_manager_sysvinit - - provides :mysql_service_manager, os: 'linux' - - action :create do - # from base - create_system_user - stop_system_service - create_config - initialize_database - configure_apparmor - end - - action :start do - template "/etc/init.d/#{mysql_name}" do - source 'sysvinit/mysqld.erb' - owner 'root' - group 'root' - mode '0755' - variables( - config: new_resource, - defaults_file: defaults_file, - error_log: error_log, - mysql_name: mysql_name, - mysqladmin_bin: mysqladmin_bin, - mysqld_safe_bin: mysqld_safe_bin, - pid_file: pid_file, - scl_name: scl_name - ) - cookbook 'mysql' - action :create - end - - service mysql_name do - supports restart: true, status: true - action [:enable, :start] - end - end - - action :stop do - service mysql_name do - supports restart: true, status: true - action [:stop] - end - end - - action :restart do - service mysql_name do - supports restart: true - action :restart - end - end - - action :reload do - service mysql_name do - action :reload - end - end - - declare_action_class.class_eval do - def stop_system_service - service system_service_name do - supports status: true - action [:stop, :disable] - end - end - - def delete_stop_service - service mysql_name do - supports status: true - action [:disable, :stop] - only_if { ::File.exist?("#{etc_dir}/init.d/#{mysql_name}") } - end - end - end - end -end diff --git a/cookbooks/mysql/libraries/mysql_service_manager_upstart.rb b/cookbooks/mysql/libraries/mysql_service_manager_upstart.rb deleted file mode 100644 index 90d4172..0000000 --- a/cookbooks/mysql/libraries/mysql_service_manager_upstart.rb +++ /dev/null @@ -1,103 +0,0 @@ -module MysqlCookbook - class MysqlServiceManagerUpstart < MysqlServiceBase - resource_name :mysql_service_manager_upstart - - provides :mysql_service_manager, platform_family: 'debian' do |_node| - Chef::Platform::ServiceHelpers.service_resource_providers.include?(:upstart) && - !Chef::Platform::ServiceHelpers.service_resource_providers.include?(:systemd) && - !Chef::Platform::ServiceHelpers.service_resource_providers.include?(:redhat) && - ::File.exist?('/sbin/status') # Fix for Docker, in 7 and 8 images /sbin/status doesn't exists and Upstart provider doesn't work - end - - action :create do - # from base - create_system_user - stop_system_service - create_config - configure_apparmor - initialize_database - end - - action :start do - template "/usr/sbin/#{mysql_name}-wait-ready" do - source 'upstart/mysqld-wait-ready.erb' - owner 'root' - group 'root' - mode '0755' - variables(socket_file: socket_file) - cookbook 'mysql' - action :create - end - - template "/etc/init/#{mysql_name}.conf" do - source 'upstart/mysqld.erb' - owner 'root' - group 'root' - mode '0644' - variables( - defaults_file: defaults_file, - mysql_name: mysql_name, - run_group: run_group, - run_user: run_user, - socket_dir: socket_dir - ) - cookbook 'mysql' - action :create - end - - service mysql_name do - provider Chef::Provider::Service::Upstart - supports status: true - action [:start] - end - end - - action :stop do - service mysql_name do - provider Chef::Provider::Service::Upstart - supports restart: true, status: true - action [:stop] - end - end - - action :restart do - # With Upstart, restarting the service doesn't behave "as expected". - # We want the post-start stanzas, which wait until the - # service is available before returning - # - # http://upstart.ubuntu.com/cookbook/#restart - service mysql_name do - provider Chef::Provider::Service::Upstart - action [:stop, :start] - end - end - - action :reload do - # With Upstart, reload just sends a HUP signal to the process. - # As far as I can tell, this doesn't work the way it's - # supposed to, so we need to actually restart the service. - service mysql_name do - provider Chef::Provider::Service::Upstart - action [:stop, :start] - end - end - - declare_action_class.class_eval do - def stop_system_service - service system_service_name do - provider Chef::Provider::Service::Upstart - supports status: true - action [:stop, :disable] - end - end - - def delete_stop_service - service mysql_name do - provider Chef::Provider::Service::Upstart - action [:disable, :stop] - only_if { ::File.exist?("#{etc_dir}/init/#{mysql_name}") } - end - end - end - end -end diff --git a/cookbooks/mysql/libraries/provider_mysql_client.rb b/cookbooks/mysql/libraries/provider_mysql_client.rb new file mode 100644 index 0000000..c796d11 --- /dev/null +++ b/cookbooks/mysql/libraries/provider_mysql_client.rb @@ -0,0 +1,39 @@ +require 'chef/provider/lwrp_base' +require_relative 'helpers' + +class Chef + class Provider + class MysqlClient < Chef::Provider::LWRPBase + include MysqlCookbook::Helpers + provides :mysql_client if defined?(provides) + + use_inline_resources if defined?(use_inline_resources) + + def whyrun_supported? + true + end + + action :create do + # From helpers.rb + configure_package_repositories + + client_package_name.each do |p| + package "#{new_resource.name} :create #{p}" do + package_name p + version new_resource.version if node['platform'] == 'smartos' + version new_resource.package_version + action :install + end + end + end + + action :delete do + parsed_package_name.each do |p| + package "#{new_resource.name} :delete #{p}" do + action :remove + end + end + end + end + end +end diff --git a/cookbooks/mysql/libraries/provider_mysql_config.rb b/cookbooks/mysql/libraries/provider_mysql_config.rb new file mode 100644 index 0000000..3732c1c --- /dev/null +++ b/cookbooks/mysql/libraries/provider_mysql_config.rb @@ -0,0 +1,59 @@ +require 'chef/provider/lwrp_base' +require_relative 'helpers' + +class Chef + class Provider + class MysqlConfig < Chef::Provider::LWRPBase + include MysqlCookbook::Helpers + provides :mysql_config if defined?(provides) + + use_inline_resources if defined?(use_inline_resources) + + def whyrun_supported? + true + end + + action :create do + group "#{new_resource.name} :create #{new_resource.group}" do + group_name new_resource.group + system true if new_resource.name == 'mysql' + action :create + end + + user "#{new_resource.name} :create #{new_resource.owner}" do + username new_resource.owner + gid new_resource.owner + system true if new_resource.name == 'mysql' + action :create + end + + directory "#{new_resource.name} :create #{include_dir}" do + path include_dir + owner new_resource.owner + group new_resource.group + mode '0750' + recursive true + action :create + end + + template "#{new_resource.name} :create #{include_dir}/#{new_resource.config_name}.cnf" do + path "#{include_dir}/#{new_resource.config_name}.cnf" + owner new_resource.owner + group new_resource.group + mode '0640' + variables(new_resource.variables) + source new_resource.source + cookbook new_resource.cookbook + action :create + end + end + + action :delete do + file "#{new_resource.name} :delete #{include_dir}/#{new_resource.config_name}.conf" do + path "#{include_dir}/#{new_resource.config_name}.conf" + action :delete + end + end + end + end +end diff --git a/cookbooks/mysql/libraries/provider_mysql_service_base.rb b/cookbooks/mysql/libraries/provider_mysql_service_base.rb new file mode 100644 index 0000000..5f19a45 --- /dev/null +++ b/cookbooks/mysql/libraries/provider_mysql_service_base.rb @@ -0,0 +1,250 @@ +require 'chef/provider/lwrp_base' +require_relative 'helpers' + +class Chef + class Provider + class MysqlServiceBase < Chef::Provider::LWRPBase + use_inline_resources if defined?(use_inline_resources) + + def whyrun_supported? + true + end + + # Mix in helpers from libraries/helpers.rb + include MysqlCookbook::Helpers + + # Service related methods referred to in the :create and :delete + # actions need to be implemented in the init system subclasses. + # + # create_stop_system_service + # delete_stop_service + + # All other methods are found in libraries/helpers.rb + # + # etc_dir, run_dir, log_dir, etc + + action :create do + # Yum, Apt, etc. From helpers.rb + configure_package_repositories + + # Software installation + package "#{new_resource.name} :create #{server_package_name}" do + package_name server_package_name + version parsed_version if node['platform'] == 'smartos' + version new_resource.package_version + action new_resource.package_action + end + + create_stop_system_service + + # Apparmor + configure_apparmor + + # System users + group "#{new_resource.name} :create mysql" do + group_name 'mysql' + action :create + end + + user "#{new_resource.name} :create mysql" do + username 'mysql' + gid 'mysql' + action :create + end + + # Yak shaving secion. Account for random errata. + # + # Turns out that mysqld is hard coded to try and read + # /etc/mysql/my.cnf, and its presence causes problems when + # setting up multiple services. + file "#{new_resource.name} :create #{prefix_dir}/etc/mysql/my.cnf" do + path "#{prefix_dir}/etc/mysql/my.cnf" + action :delete + end + + file "#{new_resource.name} :create #{prefix_dir}/etc/my.cnf" do + path "#{prefix_dir}/etc/my.cnf" + action :delete + end + + # mysql_install_db is broken on 5.6.13 + link "#{new_resource.name} :create #{prefix_dir}/usr/share/my-default.cnf" do + target_file "#{prefix_dir}/usr/share/my-default.cnf" + to "#{etc_dir}/my.cnf" + action :create + end + + # Support directories + directory "#{new_resource.name} :create #{etc_dir}" do + path etc_dir + owner new_resource.run_user + group new_resource.run_group + mode '0750' + recursive true + action :create + end + + directory "#{new_resource.name} :create #{include_dir}" do + path include_dir + owner new_resource.run_user + group new_resource.run_group + mode '0750' + recursive true + action :create + end + + directory "#{new_resource.name} :create #{run_dir}" do + path run_dir + owner new_resource.run_user + group new_resource.run_group + mode '0755' + recursive true + action :create + end + + directory "#{new_resource.name} :create #{log_dir}" do + path log_dir + owner new_resource.run_user + group new_resource.run_group + mode '0750' + recursive true + action :create + end + + directory "#{new_resource.name} :create #{parsed_data_dir}" do + path parsed_data_dir + owner new_resource.run_user + group new_resource.run_group + mode '0750' + recursive true + action :create + end + + # Main configuration file + template "#{new_resource.name} :create #{etc_dir}/my.cnf" do + path "#{etc_dir}/my.cnf" + source 'my.cnf.erb' + cookbook 'mysql' + owner new_resource.run_user + group new_resource.run_group + mode '0600' + variables( + config: new_resource, + error_log: error_log, + include_dir: include_dir, + lc_messages_dir: lc_messages_dir, + pid_file: pid_file, + socket_file: socket_file, + tmp_dir: tmp_dir, + data_dir: parsed_data_dir + ) + action :create + end + + # initialize database and create initial records + bash "#{new_resource.name} :create initial records" do + code init_records_script + returns [0, 1, 2] # facepalm + not_if "/usr/bin/test -f #{parsed_data_dir}/mysql/user.frm" + action :run + end + end + + action :delete do + # Stop the service before removing support directories + delete_stop_service + + directory "#{new_resource.name} :delete #{etc_dir}" do + path etc_dir + recursive true + action :delete + end + + directory "#{new_resource.name} :delete #{run_dir}" do + path run_dir + recursive true + action :delete + end + + directory "#{new_resource.name} :delete #{log_dir}" do + path log_dir + recursive true + action :delete + end + end + + # + # Platform specific bits + # + def configure_apparmor + # Do not add these resource if inside a container + # Only valid on Ubuntu + + unless ::File.exist?('/.dockerenv') || ::File.exist?('/.dockerinit') + if node['platform'] == 'ubuntu' + # Apparmor + package "#{new_resource.name} :create apparmor" do + package_name 'apparmor' + action :install + end + + directory "#{new_resource.name} :create /etc/apparmor.d/local/mysql" do + path '/etc/apparmor.d/local/mysql' + owner 'root' + group 'root' + mode '0755' + recursive true + action :create + end + + template "#{new_resource.name} :create /etc/apparmor.d/local/usr.sbin.mysqld" do + path '/etc/apparmor.d/local/usr.sbin.mysqld' + cookbook 'mysql' + source 'apparmor/usr.sbin.mysqld-local.erb' + owner 'root' + group 'root' + mode '0644' + action :create + notifies :restart, "service[#{new_resource.name} :create apparmor]", :immediately + end + + template "#{new_resource.name} :create /etc/apparmor.d/usr.sbin.mysqld" do + path '/etc/apparmor.d/usr.sbin.mysqld' + cookbook 'mysql' + source 'apparmor/usr.sbin.mysqld.erb' + owner 'root' + group 'root' + mode '0644' + action :create + notifies :restart, "service[#{new_resource.name} :create apparmor]", :immediately + end + + template "#{new_resource.name} :create /etc/apparmor.d/local/mysql/#{new_resource.instance}" do + path "/etc/apparmor.d/local/mysql/#{new_resource.instance}" + cookbook 'mysql' + source 'apparmor/usr.sbin.mysqld-instance.erb' + owner 'root' + group 'root' + mode '0644' + variables( + data_dir: parsed_data_dir, + mysql_name: mysql_name, + log_dir: log_dir, + run_dir: run_dir, + pid_file: pid_file, + socket_file: socket_file + ) + action :create + notifies :restart, "service[#{new_resource.name} :create apparmor]", :immediately + end + + service "#{new_resource.name} :create apparmor" do + service_name 'apparmor' + action :nothing + end + end + end + end + end + end +end diff --git a/cookbooks/mysql/libraries/provider_mysql_service_smf.rb b/cookbooks/mysql/libraries/provider_mysql_service_smf.rb new file mode 100644 index 0000000..cc208c1 --- /dev/null +++ b/cookbooks/mysql/libraries/provider_mysql_service_smf.rb @@ -0,0 +1,91 @@ +class Chef + class Provider + class MysqlServiceSmf < Chef::Provider::MysqlServiceBase + # FIXME: we should have a service_helper to determine if the platform supports SMF similarly + # to how we handle systemd on linux + if defined?(provides) # foodcritic ~FC023 + provides :mysql_service, os: %w(solaris2 omnios smartos openindiana opensolaris nexentacore) do + File.exist?('/usr/sbin/svccfg') + end + end + + action :start do + method_script_path = "/lib/svc/method/#{mysql_name}" if node['platform'] == 'omnios' + method_script_path = "/opt/local/lib/svc/method/#{mysql_name}" if node['platform'] == 'smartos' + + template "#{new_resource.name} :start #{method_script_path}" do + path method_script_path + cookbook 'mysql' + source 'smf/svc.method.mysqld.erb' + owner 'root' + group 'root' + mode '0555' + variables( + base_dir: base_dir, + data_dir: parsed_data_dir, + defaults_file: defaults_file, + error_log: error_log, + mysql_name: mysql_name, + mysqld_bin: mysqld_bin, + pid_file: pid_file + ) + action :create + end + + smf "#{new_resource.name} :start #{mysql_name}" do + name mysql_name + user new_resource.run_user + group new_resource.run_group + start_command "#{method_script_path} start" + end + + service "#{new_resource.name} :start #{mysql_name}" do + service_name mysql_name + provider Chef::Provider::Service::Solaris + supports restart: true + action [:enable] + end + end + + action :stop do + service "#{new_resource.name} :stop #{mysql_name}" do + service_name mysql_name + provider Chef::Provider::Service::Solaris + supports restart: true + action :stop + end + end + + action :restart do + service "#{new_resource.name} :restart #{mysql_name}" do + service_name mysql_name + provider Chef::Provider::Service::Solaris + supports restart: true + action :restart + end + end + + action :reload do + service "#{new_resource.name} :reload #{mysql_name}" do + provider Chef::Provider::Service::Solaris + service_name mysql_name + supports reload: true + action :reload + end + end + + def create_stop_system_service + # nothing to do here + end + + def delete_stop_service + service "#{new_resource.name} :delete #{mysql_name}" do + service_name mysql_name + provider Chef::Provider::Service::Solaris + supports restart: true + action :stop + end + end + end + end +end diff --git a/cookbooks/mysql/libraries/provider_mysql_service_systemd.rb b/cookbooks/mysql/libraries/provider_mysql_service_systemd.rb new file mode 100644 index 0000000..7ef415b --- /dev/null +++ b/cookbooks/mysql/libraries/provider_mysql_service_systemd.rb @@ -0,0 +1,135 @@ +require_relative 'provider_mysql_service_base' + +class Chef + class Provider + class MysqlServiceSystemd < Chef::Provider::MysqlServiceBase + if defined?(provides) # foodcritic ~FC023 + provides :mysql_service, os: 'linux' do + Chef::Platform::ServiceHelpers.service_resource_providers.include?(:systemd) + end + end + + action :start do + # Needed for Debian / Ubuntu + directory '/usr/libexec' do + owner 'root' + group 'root' + mode '0755' + action :create + end + + # this script is called by the main systemd unit file, and + # spins around until the service is actually up and running. + template "#{new_resource.name} :start /usr/libexec/#{mysql_name}-wait-ready" do + path "/usr/libexec/#{mysql_name}-wait-ready" + source 'systemd/mysqld-wait-ready.erb' + owner 'root' + group 'root' + mode '0755' + variables(socket_file: socket_file) + cookbook 'mysql' + action :create + end + + # this is the main systemd unit file + template "#{new_resource.name} :start /lib/systemd/system/#{mysql_name}.service" do + path "/lib/systemd/system/#{mysql_name}.service" + source 'systemd/mysqld.service.erb' + owner 'root' + group 'root' + mode '0644' + variables( + config: new_resource, + etc_dir: etc_dir, + base_dir: base_dir, + mysqld_bin: mysqld_bin + ) + cookbook 'mysql' + notifies :run, "execute[#{new_resource.name} :start systemctl daemon-reload]", :immediately + action :create + end + + # avoid 'Unit file changed on disk' warning + execute "#{new_resource.name} :start systemctl daemon-reload" do + command '/bin/systemctl daemon-reload' + action :nothing + end + + # tmpfiles.d config so the service survives reboot + template "#{new_resource.name} :start /usr/lib/tmpfiles.d/#{mysql_name}.conf" do + path "/usr/lib/tmpfiles.d/#{mysql_name}.conf" + source 'tmpfiles.d.conf.erb' + owner 'root' + group 'root' + mode '0644' + variables( + run_dir: run_dir, + run_user: new_resource.run_user, + run_group: new_resource.run_group + ) + cookbook 'mysql' + action :create + end + + # service management resource + service "#{new_resource.name} :start #{mysql_name}" do + service_name mysql_name + provider Chef::Provider::Service::Systemd + supports restart: true, status: true + action [:enable, :start] + end + end + + action :stop do + # service management resource + service "#{new_resource.name} :stop #{mysql_name}" do + service_name mysql_name + provider Chef::Provider::Service::Systemd + supports status: true + action [:disable, :stop] + only_if { ::File.exist?("/usr/lib/systemd/system/#{mysql_name}.service") } + end + end + + action :restart do + # service management resource + service "#{new_resource.name} :restart #{mysql_name}" do + service_name mysql_name + provider Chef::Provider::Service::Systemd + supports restart: true + action :restart + end + end + + action :reload do + # service management resource + service "#{new_resource.name} :reload #{mysql_name}" do + service_name mysql_name + provider Chef::Provider::Service::Systemd + action :reload + end + end + + def create_stop_system_service + # service management resource + service "#{new_resource.name} :create mysql" do + service_name system_service_name + provider Chef::Provider::Service::Systemd + supports status: true + action [:stop, :disable] + end + end + + def delete_stop_service + # service management resource + service "#{new_resource.name} :delete #{mysql_name}" do + service_name mysql_name + provider Chef::Provider::Service::Systemd + supports status: true + action [:disable, :stop] + only_if { ::File.exist?("/usr/lib/systemd/system/#{mysql_name}.service") } + end + end + end + end +end diff --git a/cookbooks/mysql/libraries/provider_mysql_service_sysvinit.rb b/cookbooks/mysql/libraries/provider_mysql_service_sysvinit.rb new file mode 100644 index 0000000..b3f2259 --- /dev/null +++ b/cookbooks/mysql/libraries/provider_mysql_service_sysvinit.rb @@ -0,0 +1,89 @@ +require_relative 'provider_mysql_service_base' + +class Chef + class Provider + class MysqlServiceSysvinit < Chef::Provider::MysqlServiceBase + provides :mysql_service, os: '!windows' if defined?(provides) + + action :start do + template "#{new_resource.name} :start /etc/init.d/#{mysql_name}" do + path "/etc/init.d/#{mysql_name}" + source 'sysvinit/mysqld.erb' + owner 'root' + group 'root' + mode '0755' + variables( + config: new_resource, + defaults_file: defaults_file, + error_log: error_log, + mysql_name: mysql_name, + mysqladmin_bin: mysqladmin_bin, + mysqld_safe_bin: mysqld_safe_bin, + pid_file: pid_file, + scl_name: scl_name + ) + cookbook 'mysql' + action :create + end + + service "#{new_resource.name} :start #{mysql_name}" do + service_name mysql_name + provider Chef::Provider::Service::Init::Redhat if node['platform_family'] == 'redhat' + provider Chef::Provider::Service::Init::Insserv if node['platform_family'] == 'debian' + supports restart: true, status: true + action [:enable, :start] + end + end + + action :stop do + service "#{new_resource.name} :stop #{mysql_name}" do + service_name mysql_name + provider Chef::Provider::Service::Init::Redhat if node['platform_family'] == 'redhat' + provider Chef::Provider::Service::Init::Insserv if node['platform_family'] == 'debian' + supports restart: true, status: true + action [:stop] + end + end + + action :restart do + service "#{new_resource.name} :restart #{mysql_name}" do + service_name mysql_name + provider Chef::Provider::Service::Init::Redhat if node['platform_family'] == 'redhat' + provider Chef::Provider::Service::Init::Insserv if node['platform_family'] == 'debian' + supports restart: true + action :restart + end + end + + action :reload do + service "#{new_resource.name} :reload #{mysql_name}" do + service_name mysql_name + provider Chef::Provider::Service::Init::Redhat if node['platform_family'] == 'redhat' + provider Chef::Provider::Service::Init::Insserv if node['platform_family'] == 'debian' + action :reload + end + end + + def create_stop_system_service + service "#{new_resource.name} :create #{system_service_name}" do + service_name system_service_name + provider Chef::Provider::Service::Init::Redhat if node['platform_family'] == 'redhat' + provider Chef::Provider::Service::Init::Insserv if node['platform_family'] == 'debian' + supports status: true + action [:stop, :disable] + end + end + + def delete_stop_service + service "#{new_resource.name} :delete #{mysql_name}" do + service_name mysql_name + provider Chef::Provider::Service::Init::Redhat if node['platform_family'] == 'redhat' + provider Chef::Provider::Service::Init::Insserv if node['platform_family'] == 'debian' + supports status: true + action [:disable, :stop] + only_if { ::File.exist?("#{etc_dir}/init.d/#{mysql_name}") } + end + end + end + end +end diff --git a/cookbooks/mysql/libraries/provider_mysql_service_upstart.rb b/cookbooks/mysql/libraries/provider_mysql_service_upstart.rb new file mode 100644 index 0000000..3a328b6 --- /dev/null +++ b/cookbooks/mysql/libraries/provider_mysql_service_upstart.rb @@ -0,0 +1,114 @@ +require_relative 'provider_mysql_service_base' + +class Chef + class Provider + class MysqlServiceUpstart < Chef::Provider::MysqlServiceBase + if defined?(provides) # foodcritic ~FC023 + provides :mysql_service, os: 'linux' do + Chef::Platform::ServiceHelpers.service_resource_providers.include?(:upstart) && + !Chef::Platform::ServiceHelpers.service_resource_providers.include?(:redhat) + end + end + + action :start do + template "#{new_resource.name} :start /usr/sbin/#{mysql_name}-wait-ready" do + path "/usr/sbin/#{mysql_name}-wait-ready" + source 'upstart/mysqld-wait-ready.erb' + owner 'root' + group 'root' + mode '0755' + variables(socket_file: socket_file) + cookbook 'mysql' + action :create + end + + template "#{new_resource.name} :start /etc/init/#{mysql_name}.conf" do + path "/etc/init/#{mysql_name}.conf" + source 'upstart/mysqld.erb' + owner 'root' + group 'root' + mode '0644' + variables( + defaults_file: defaults_file, + mysql_name: mysql_name, + run_group: new_resource.run_group, + run_user: new_resource.run_user, + socket_dir: socket_dir + ) + cookbook 'mysql' + action :create + end + + service "#{new_resource.name} :start #{mysql_name}" do + service_name mysql_name + provider Chef::Provider::Service::Upstart + supports status: true + action [:start] + end + end + + action :stop do + service "#{new_resource.name} :stop #{mysql_name}" do + service_name mysql_name + provider Chef::Provider::Service::Upstart + supports restart: true, status: true + action [:stop] + end + end + + action :restart do + # With Upstart, restarting the service doesn't behave "as expected". + # We want the post-start stanzas, which wait until the + # service is available before returning + # + # http://upstart.ubuntu.com/cookbook/#restart + service "#{new_resource.name} :restart stop #{mysql_name}" do + service_name mysql_name + provider Chef::Provider::Service::Upstart + action :stop + end + + service "#{new_resource.name} :restart start #{mysql_name}" do + service_name mysql_name + provider Chef::Provider::Service::Upstart + action :start + end + end + + action :reload do + # With Upstart, reload just sends a HUP signal to the process. + # As far as I can tell, this doesn't work the way it's + # supposed to, so we need to actually restart the service. + service "#{new_resource.name} :reload stop #{mysql_name}" do + service_name mysql_name + provider Chef::Provider::Service::Upstart + action :stop + end + + service "#{new_resource.name} :reload start #{mysql_name}" do + service_name mysql_name + provider Chef::Provider::Service::Upstart + action :start + end + end + + def create_stop_system_service + service "#{new_resource.name} :create #{system_service_name}" do + service_name system_service_name + provider Chef::Provider::Service::Upstart + supports status: true + action [:stop, :disable] + end + end + + def delete_stop_service + service "#{new_resource.name} :delete #{mysql_name}" do + service_name mysql_name + provider Chef::Provider::Service::Upstart + action [:disable, :stop] + only_if { ::File.exist?("#{etc_dir}/init/#{mysql_name}") } + end + end + end + end +end diff --git a/cookbooks/mysql/libraries/provider_priority_linux.rb b/cookbooks/mysql/libraries/provider_priority_linux.rb new file mode 100644 index 0000000..cea5b11 --- /dev/null +++ b/cookbooks/mysql/libraries/provider_priority_linux.rb @@ -0,0 +1,45 @@ + +begin + require 'chef/platform/provider_priority_map' +rescue LoadError # rubocop: disable Lint/HandleExceptions +end + +require_relative 'provider_mysql_service_smf' +require_relative 'provider_mysql_service_systemd' +require_relative 'provider_mysql_service_sysvinit' +require_relative 'provider_mysql_service_upstart' +require_relative 'provider_mysql_config' +require_relative 'provider_mysql_client' + +if defined? Chef::Platform::ProviderPriorityMap + Chef::Platform::ProviderPriorityMap.instance.priority( + :mysql_service, + [Chef::Provider::MysqlServiceSystemd, Chef::Provider::MysqlServiceUpstart, Chef::Provider::MysqlServiceSysvinit], + os: 'linux' + ) +else + # provider mappings for Chef 11 + + # systemd service + Chef::Platform.set platform: :fedora, version: '>= 19', resource: :mysql_service, provider: Chef::Provider::MysqlServiceSystemd + Chef::Platform.set platform: :redhat, version: '>= 7.0', resource: :mysql_service, provider: Chef::Provider::MysqlServiceSystemd + Chef::Platform.set platform: :centos, version: '>= 7.0', resource: :mysql_service, provider: Chef::Provider::MysqlServiceSystemd + Chef::Platform.set platform: :scientific, version: '>= 7.0', resource: :mysql_service, provider: Chef::Provider::MysqlServiceSystemd + Chef::Platform.set platform: :oracle, version: '>= 7.0', resource: :mysql_service, provider: Chef::Provider::MysqlServiceSystemd + + # smf service + Chef::Platform.set platform: :omnios, resource: :mysql_service, provider: Chef::Provider::MysqlServiceSmf + Chef::Platform.set platform: :smartos, resource: :mysql_service, provider: Chef::Provider::MysqlServiceSmf + + # upstart service + Chef::Platform.set platform: :ubuntu, resource: :mysql_service, provider: Chef::Provider::MysqlServiceUpstart + + # default service + Chef::Platform.set resource: :mysql_service, provider: Chef::Provider::MysqlServiceSysvinit + + # config + Chef::Platform.set resource: :mysql_config, provider: Chef::Provider::MysqlConfig + + # client + Chef::Platform.set resource: :mysql_client, provider: Chef::Provider::MysqlClient +end diff --git a/cookbooks/mysql/libraries/resource_mysql_client.rb b/cookbooks/mysql/libraries/resource_mysql_client.rb new file mode 100644 index 0000000..8585dbe --- /dev/null +++ b/cookbooks/mysql/libraries/resource_mysql_client.rb @@ -0,0 +1,18 @@ +require 'chef/resource/lwrp_base' + +class Chef + class Resource + class MysqlClient < Chef::Resource::LWRPBase + provides :mysql_client + + self.resource_name = :mysql_client + actions :create, :delete + default_action :create + + attribute :client_name, kind_of: String, name_attribute: true, required: true + attribute :package_name, kind_of: Array, default: nil + attribute :package_version, kind_of: String, default: nil + attribute :version, kind_of: String, default: nil # mysql_version + end + end +end diff --git a/cookbooks/mysql/libraries/resource_mysql_config.rb b/cookbooks/mysql/libraries/resource_mysql_config.rb new file mode 100644 index 0000000..a8767ce --- /dev/null +++ b/cookbooks/mysql/libraries/resource_mysql_config.rb @@ -0,0 +1,22 @@ +require 'chef/resource/lwrp_base' + +class Chef + class Resource + class MysqlConfig < Chef::Resource::LWRPBase + provides :mysql_config + + self.resource_name = :mysql_config + actions :create, :delete + default_action :create + + attribute :config_name, kind_of: String, name_attribute: true, required: true + attribute :cookbook, kind_of: String, default: nil + attribute :group, kind_of: String, default: 'mysql' + attribute :instance, kind_of: String, default: 'default' + attribute :owner, kind_of: String, default: 'mysql' + attribute :source, kind_of: String, default: nil + attribute :variables, kind_of: [Hash], default: nil + attribute :version, kind_of: String, default: nil + end + end +end diff --git a/cookbooks/mysql/libraries/resource_mysql_service.rb b/cookbooks/mysql/libraries/resource_mysql_service.rb new file mode 100644 index 0000000..8d4f5d3 --- /dev/null +++ b/cookbooks/mysql/libraries/resource_mysql_service.rb @@ -0,0 +1,31 @@ +require 'chef/resource/lwrp_base' + +class Chef + class Resource + class MysqlService < Chef::Resource::LWRPBase + provides :mysql_service + + self.resource_name = :mysql_service + actions :create, :delete, :start, :stop, :restart, :reload + default_action :create + + attribute :charset, kind_of: String, default: 'utf8' + attribute :data_dir, kind_of: String, default: nil + attribute :initial_root_password, kind_of: String, default: 'ilikerandompasswords' + attribute :instance, kind_of: String, name_attribute: true + attribute :package_action, kind_of: Symbol, default: :install + attribute :package_name, kind_of: String, default: nil + attribute :package_version, kind_of: String, default: nil + attribute :bind_address, kind_of: String, default: nil + attribute :port, kind_of: [String, Integer], default: '3306' + attribute :run_group, kind_of: String, default: 'mysql' + attribute :run_user, kind_of: String, default: 'mysql' + attribute :socket, kind_of: String, default: nil + attribute :mysqld_options, kind_of: Hash, default: {} + attribute :version, kind_of: String, default: nil + attribute :error_log, kind_of: String, default: nil + attribute :tmp_dir, kind_of: String, default: nil + attribute :pid_file, kind_of: String, default: nil + end + end +end diff --git a/cookbooks/mysql/metadata.json b/cookbooks/mysql/metadata.json index 22bd441..54c8e71 100644 --- a/cookbooks/mysql/metadata.json +++ b/cookbooks/mysql/metadata.json @@ -1 +1 @@ -{"name":"mysql","version":"8.4.0","description":"Provides mysql_service, mysql_config, and mysql_client resources","long_description":"","maintainer":"Chef Software, Inc.","maintainer_email":"cookbooks@chef.io","license":"Apache-2.0","platforms":{"redhat":">= 6.0","centos":">= 6.0","scientific":">= 6.0","oracle":">= 6.0","amazon":">= 0.0.0","fedora":">= 0.0.0","debian":">= 7.0","ubuntu":">= 12.04","opensuse":">= 13.0","opensuseleap":">= 0.0.0","suse":">= 12.0"},"dependencies":{},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{},"source_url":"https://github.com/chef-cookbooks/mysql","issues_url":"https://github.com/chef-cookbooks/mysql/issues","chef_version":[[">= 12.1"]],"ohai_version":[]} \ No newline at end of file +{"name":"mysql","version":"6.1.3","description":"Provides mysql_service, mysql_config, and mysql_client resources","long_description":"# MySQL Cookbook\n\n[![Build Status](https://travis-ci.org/chef-cookbooks/mysql.svg?branch=master)](https://travis-ci.org/chef-cookbooks/mysql) [![Cookbook Version](https://img.shields.io/cookbook/v/mysql.svg)](https://supermarket.chef.io/cookbooks/mysql)\n\nThe Mysql Cookbook is a library cookbook that provides resource primitives (LWRPs) for use in recipes. It is designed to be a reference example for creating highly reusable cross-platform cookbooks.\n\n## Scope\n\nThis cookbook is concerned with the \"MySQL Community Server\", particularly those shipped with F/OSS Unix and Linux distributions. It does not address forks or value-added repackaged MySQL distributions like Drizzle, MariaDB, or Percona.\n\n## Requirements\n\n- Chef 11 or higher\n- Ruby 1.9 or higher (preferably from the Chef full-stack installer)\n- Network accessible package repositories\n- 'recipe[selinux::disabled]' on RHEL platforms\n\n## Platform Support\n\nThe following platforms have been tested with Test Kitchen:\n\n```\n|----------------+-----+-----+-----+-----+-----|\n| | 5.0 | 5.1 | 5.5 | 5.6 | 5.7 |\n|----------------+-----+-----+-----+-----+-----|\n| debian-7 | | | X | | |\n|----------------+-----+-----+-----+-----+-----|\n| ubuntu-12.04 | | | X | | |\n|----------------+-----+-----+-----+-----+-----|\n| ubuntu-14.04 | | | X | X | |\n|----------------+-----+-----+-----+-----+-----|\n| ubuntu-15.04 | | | | X | |\n|----------------+-----+-----+-----+-----+-----|\n| centos-5 | X | X | X | X | X |\n|----------------+-----+-----+-----+-----+-----|\n| centos-6 | | X | X | X | X |\n|----------------+-----+-----+-----+-----+-----|\n| centos-7 | | | X | X | X |\n|----------------+-----+-----+-----+-----+-----|\n| amazon | | | X | X | X |\n|----------------+-----+-----+-----+-----+-----|\n| fedora-22 | | | X | X | X |\n|----------------+-----+-----+-----+-----+-----|\n| fedora-23 | | | X | X | X |\n|----------------+-----+-----+-----+-----+-----|\n```\n\n## Cookbook Dependencies\n\n- yum-mysql-community\n- smf\n\n## Usage\n\nPlace a dependency on the mysql cookbook in your cookbook's metadata.rb\n\n```ruby\ndepends 'mysql', '~> 6.0'\n```\n\nThen, in a recipe:\n\n```ruby\nmysql_service 'foo' do\n port '3306'\n version '5.5'\n initial_root_password 'change me'\n action [:create, :start]\nend\n```\n\nThe service name on the OS is `mysql-foo`. You can manually start and stop it with `service mysql-foo start` and `service mysql-foo stop`.\n\nThe configuration file is at `/etc/mysql-foo/my.cnf`. It contains the minimum options to get the service running. It looks like this.\n\n```\n# Chef generated my.cnf for instance mysql-foo\n\n[client]\ndefault-character-set = utf8\nport = 3306\nsocket = /var/run/mysql-foo/mysqld.sock\n\n[mysql]\ndefault-character-set = utf8\n\n[mysqld]\nuser = mysql\npid-file = /var/run/mysql-foo/mysqld.pid\nsocket = /var/run/mysql-foo/mysqld.sock\nport = 3306\ndatadir = /var/lib/mysql-foo\ntmpdir = /tmp\nlog-error = /var/log/mysql-foo/error.log\n!includedir /etc/mysql-foo/conf.d\n\n[mysqld_safe]\nsocket = /var/run/mysql-foo/mysqld.sock\n```\n\nYou can put extra configuration into the conf.d directory by using the `mysql_config` resource, like this:\n\n```ruby\nmysql_service 'foo' do\n port '3306'\n version '5.5'\n initial_root_password 'change me'\n action [:create, :start]\nend\n\nmysql_config 'foo' do\n source 'my_extra_settings.erb'\n notifies :restart, 'mysql_service[foo]'\n action :create\nend\n```\n\nYou are responsible for providing `my_extra_settings.erb` in your own cookbook's templates folder.\n\n## Connecting with the mysql CLI command\n\nLogging into the machine and typing `mysql` with no extra arguments will fail. You need to explicitly connect over the socket with `mysql -S /var/run/mysql-foo/mysqld.sock`, or over the network with `mysql -h 127.0.0.1`\n\n## Upgrading from older version of the mysql cookbook\n\n- It is strongly recommended that you rebuild the machine from scratch. This is easy if you have your `data_dir` on a dedicated mount point. If you _must_ upgrade in-place, follow the instructions below.\n- The 6.x series supports multiple service instances on a single machine. It dynamically names the support directories and service names. `/etc/mysql becomes /etc/mysql-instance_name`. Other support directories in `/var` `/run` etc work the same way. Make sure to specify the `data_dir` property on the `mysql_service` resource to point to the old `/var/lib/mysql` directory.\n\n## Resources Overview\n\n### mysql_service\n\nThe `mysql_service` resource manages the basic plumbing needed to get a MySQL server instance running with minimal configuration.\n\nThe `:create` action handles package installation, support directories, socket files, and other operating system level concerns. The internal configuration file contains just enough to get the service up and running, then loads extra configuration from a conf.d directory. Further configurations are managed with the `mysql_config` resource.\n\n- If the `data_dir` is empty, a database will be initialized, and a\n- root user will be set up with `initial_root_password`. If this\n- directory already contains database files, no action will be taken.\n\nThe `:start` action starts the service on the machine using the appropriate provider for the platform. The `:start` action should be omitted when used in recipes designed to build containers.\n\n#### Example\n\n```ruby\nmysql_service 'default' do\n version '5.7'\n bind_address '0.0.0.0'\n port '3306'\n data_dir '/data'\n initial_root_password 'Ch4ng3me'\n action [:create, :start]\nend\n```\n\nPlease note that when using `notifies` or `subscribes`, the resource to reference is `mysql_service[name]`, not `service[mysql]`.\n\n#### Parameters\n\n- `charset` - specifies the default character set. Defaults to `utf8`.\n- `data_dir` - determines where the actual data files are kept on the machine. This is useful when mounting external storage. When omitted, it will default to the platform's native location.\n- `error_log` - Tunable location of the error_log\n- `initial_root_password` - allows the user to specify the initial root password for mysql when initializing new databases. This can be set explicitly in a recipe, driven from a node attribute, or from data_bags. When omitted, it defaults to `ilikerandompasswords`. Please be sure to change it.\n- `instance` - A string to identify the MySQL service. By convention, to allow for multiple instances of the `mysql_service`, directories and files on disk are named `mysql-`. Defaults to the resource name.\n- `package_action` - Defaults to `:install`.\n- `package_name` - Defaults to a value looked up in an internal map.\n- `package_version` - Specific version of the package to install,passed onto the underlying package manager. Defaults to `nil`.\n- `bind_address` - determines the listen IP address for the mysqld service. When omitted, it will be determined by MySQL. If the address is \"regular\" IPv4/IPv6address (e.g 127.0.0.1 or ::1), the server accepts TCP/IP connections only for that particular address. If the address is \"0.0.0.0\" (IPv4) or \"::\" (IPv6), the server accepts TCP/IP connections on all IPv4 or IPv6 interfaces.\n- `mysqld_options` - A key value hash of options to be rendered into the main my.cnf. WARNING - It is highly recommended that you use the `mysql_config` resource instead of sending extra config into a `mysql_service` resource. This will allow you to set up notifications and subscriptions between the service and its configuration. That being said, this can be useful for adding extra options needed for database initialization at first run.\n- `port` - determines the listen port for the mysqld service. When omitted, it will default to '3306'.\n- `run_group` - The name of the system group the `mysql_service` should run as. Defaults to 'mysql'.\n- `run_user` - The name of the system user the `mysql_service` should run as. Defaults to 'mysql'.\n- `pid_file` - Tunable location of the pid file.\n- `socket` - determines where to write the socket file for the `mysql_service` instance. Useful when configuring clients on the same machine to talk over socket and skip the networking stack. Defaults to a calculated value based on platform and instance name.\n- `tmp_dir` - Tunable location of the tmp_dir\n- `version` - allows the user to select from the versions available for the platform, where applicable. When omitted, it will install the default MySQL version for the target platform. Available version numbers are `5.0`, `5.1`, `5.5`, `5.6`, and `5.7`, depending on platform.\n\n#### Actions\n\n- `:create` - Configures everything but the underlying operating system service.\n- `:delete` - Removes everything but the package and data_dir.\n- `:start` - Starts the underlying operating system service\n- `:stop`- Stops the underlying operating system service\n- `:restart` - Restarts the underlying operating system service\n- `:reload` - Reloads the underlying operating system service\n\n#### Providers\n\nChef selects the appropriate provider based on platform and version, but you can specify one if your platform support it.\n\n```ruby\nmysql_service[instance-1] do\n port '1234'\n data_dir '/mnt/lottadisk'\n provider Chef::Provider::MysqlServiceSysvinit\n action [:create, :start]\nend\n```\n\n- `Chef::Provider::MysqlServiceBase` - Configures everything needed to run a MySQL service except the platform service facility. This provider should never be used directly. The `:start`, `:stop`, `:restart`, and `:reload` actions are stubs meant to be overridden by the providers below.\n- `Chef::Provider::MysqlServiceSmf` - Starts a `mysql_service` using the Service Management Facility, used by Solaris and Illumos. Manages the FMRI and method script.\n- `Chef::Provider::MysqlServiceSystemd` - Starts a `mysql_service` using SystemD. Manages the unit file and activation state\n- `Chef::Provider::MysqlServiceSysvinit` - Starts a `mysql_service` using SysVinit. Manages the init script and status.\n- `Chef::Provider::MysqlServiceUpstart` - Starts a `mysql_service` using Upstart. Manages job definitions and status.\n\n### mysql_config\n\nThe `mysql_config` resource is a wrapper around the core Chef `template` resource. Instead of a `path` parameter, it uses the `instance` parameter to calculate the path on the filesystem where file is rendered.\n\n#### Example\n\n```ruby\nmysql_config[default] do\n source 'site.cnf.erb'\n action :create\nend\n```\n\n#### Parameters\n\n- `config_name` - The base name of the configuration file to be rendered into the conf.d directory on disk. Defaults to the resource name.\n- `cookbook` - The name of the cookbook to look for the template source. Defaults to nil\n- `group` - System group for file ownership. Defaults to 'mysql'.\n- `instance` - Name of the `mysql_service` instance the config is meant for. Defaults to 'default'.\n- `owner` - System user for file ownership. Defaults to 'mysql'.\n- `source` - Template in cookbook to be rendered.\n- `variables` - Variables to be passed to the underlying `template` resource.\n- `version` - Version of the `mysql_service` instance the config is meant for. Used to calculate path. Only necessary when using packages with unique configuration paths, such as RHEL Software Collections or OmniOS. Defaults to 'nil'\n\n#### Actions\n\n- `:create` - Renders the template to disk at a path calculated using the instance parameter.\n- `:delete` - Deletes the file from the conf.d directory calculated using the instance parameter.\n\n#### More Examples\n\n```ruby\nmysql_service 'instance-1' do\n action [:create, :start]\nend\n\nmysql_service 'instance-2' do\n action [:create, :start]\nend\n\nmysql_config 'logging' do\n instance 'instance-1'\n source 'logging.cnf.erb'\n action :create\n notifies :restart, 'mysql_service[instance-1]'\nend\n\nmysql_config 'security settings for instance-2' do\n config_name 'security'\n instance 'instance-2'\n source 'security_stuff.cnf.erb'\n variables(:foo => 'bar')\n action :create\n notifies :restart, 'mysql_service[instance-2]'\nend\n```\n\n### mysql_client\n\nThe `mysql_client` resource manages the MySQL client binaries and development libraries.\n\nIt is an example of a \"singleton\" resource. Declaring two `mysql_client` resources on a machine usually won't yield two separate copies of the client binaries, except for platforms that support multiple versions (RHEL SCL, OmniOS).\n\n#### Example\n\n```ruby\nmysql_client 'default' do\n action :create\nend\n```\n\n#### Parameters\n\n- `package_name` - An array of packages to be installed. Defaults to a value looked up in an internal map.\n- `package_version` - Specific versions of the package to install, passed onto the underlying package manager. Defaults to `nil`.\n- `version` - Major MySQL version number of client packages. Only valid on for platforms that support multiple versions, such as RHEL via Software Collections and OmniOS.\n\n#### Actions\n\n- `:create` - Installs the client software\n- `:delete` - Removes the client software\n\n## Advanced Usage Examples\n\nThere are a number of configuration scenarios supported by the use of resource primitives in recipes. For example, you might want to run multiple MySQL services, as different users, and mount block devices that contain pre-existing databases.\n\n### Multiple Instances as Different Users\n\n```ruby\n# instance-1\nuser 'alice' do\n action :create\nend\n\ndirectory '/mnt/data/mysql/instance-1' do\n owner 'alice'\n action :create\nend\n\nmount '/mnt/data/mysql/instance-1' do\n device '/dev/sdb1'\n fstype 'ext4'\n action [:mount, :enable]\nend\n\nmysql_service 'instance-1' do\n port '3307'\n run_user 'alice'\n data_dir '/mnt/data/mysql/instance-1'\n action [:create, :start]\nend\n\nmysql_config 'site config for instance-1' do\n instance 'instance-1'\n source 'instance-1.cnf.erb'\n notifies :restart, 'mysql_service[instance-1]'\nend\n\n# instance-2\nuser 'bob' do\n action :create\nend\n\ndirectory '/mnt/data/mysql/instance-2' do\n owner 'bob'\n action :create\nend\n\nmount '/mnt/data/mysql/instance-2' do\n device '/dev/sdc1'\n fstype 'ext3'\n action [:mount, :enable]\nend\n\nmysql_service 'instance-2' do\n port '3308'\n run_user 'bob'\n data_dir '/mnt/data/mysql/instance-2'\n action [:create, :start]\nend\n\nmysql_config 'site config for instance-2' do\n instance 'instance-2'\n source 'instance-2.cnf.erb'\n notifies :restart, 'mysql_service[instance-2]'\nend\n```\n\n### Replication Testing\n\nUse multiple `mysql_service` instances to test a replication setup. This particular example serves as a smoke test in Test Kitchen because it exercises different resources and requires service restarts.\n\n\n\n## Frequently Asked Questions\n\n### How do I run this behind my firewall?\n\nOn Linux, the `mysql_service` resource uses the platform's underlying package manager to install software. For this to work behind firewalls, you'll need to either:\n\n- Configure the system yum/apt utilities to use a proxy server that\n- can reach the Internet\n- Host a package repository on a network that the machine can talk to\n\nOn the RHEL platform_family, applying the `yum::default` recipe will allow you to drive the `yum_globalconfig` resource with attributes to change the global yum proxy settings.\n\nIf hosting repository mirrors, applying one of the following recipes and adjust the settings with node attributes.\n\n- `recipe[yum-centos::default]` from the Supermarket\n\n \n\n \n\n- `recipe[yum-mysql-community::default]` from the Supermarket\n\n \n\n \n\n### The mysql command line doesn't work\n\nIf you log into the machine and type `mysql`, you may see an error like this one:\n\n`Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock'`\n\nThis is because MySQL is hardcoded to read the defined default my.cnf file, typically at /etc/my.cnf, and this LWRP deletes it to prevent overlap among multiple MySQL configurations.\n\nTo connect to the socket from the command line, check the socket in the relevant my.cnf file and use something like this:\n\n`mysql -S /var/run/mysql-foo/mysqld.sock -Pwhatever`\n\nOr to connect over the network, use something like this: connect over the network..\n\n`mysql -h 127.0.0.1 -Pwhatever`\n\nThese network or socket ssettings can also be put in you $HOME/.my.cnf, if preferred.\n\n### What about MariaDB, Percona, Drizzle, WebScaleSQL, etc.\n\nMySQL forks are purposefully out of scope for this cookbook. This is mostly to reduce the testing matrix to a manageable size. Cookbooks for these technologies can easily be created by copying and adapting this cookbook. However, there will be differences.\n\nPackage repository locations, package version names, software major version numbers, supported platform matrices, and the availability of software such as XtraDB and Galera are the main reasons that creating multiple cookbooks to make sense.\n\n## Warnings\n\n## Hacking / Testing / TODO\n\nPlease refer to the HACKING.md\n\n## License & Authors\n\n- Author:: Joshua Timberman ([joshua@chef.io](mailto:joshua@chef.io))\n- Author:: AJ Christensen ([aj@chef.io](mailto:aj@chef.io))\n- Author:: Seth Chisamore ([schisamo@chef.io](mailto:schisamo@chef.io))\n- Author:: Brian Bianco ([brian.bianco@gmail.com](mailto:brian.bianco@gmail.com))\n- Author:: Jesse Howarth ([him@jessehowarth.com](mailto:him@jessehowarth.com))\n- Author:: Andrew Crump ([andrew@kotirisoftware.com](mailto:andrew@kotirisoftware.com))\n- Author:: Christoph Hartmann ([chris@lollyrock.com](mailto:chris@lollyrock.com))\n- Author:: Sean OMeara ([sean@chef.io](mailto:sean@chef.io))\n\n```text\nCopyright:: 2009-2014 Chef Software, Inc\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```\n","maintainer":"Chef Software, Inc.","maintainer_email":"cookbooks@chef.io","license":"Apache 2.0","platforms":{"amazon":">= 0.0.0","redhat":">= 0.0.0","centos":">= 0.0.0","scientific":">= 0.0.0","fedora":">= 0.0.0","debian":">= 0.0.0","ubuntu":">= 0.0.0","smartos":">= 0.0.0","omnios":">= 0.0.0","suse":">= 0.0.0"},"dependencies":{"yum-mysql-community":">= 0.0.0","smf":">= 0.0.0"},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{}} \ No newline at end of file diff --git a/cookbooks/mysql/templates/default/apparmor/usr.sbin.mysqld-instance.erb b/cookbooks/mysql/templates/default/apparmor/usr.sbin.mysqld-instance.erb index 130beb7..430a311 100644 --- a/cookbooks/mysql/templates/default/apparmor/usr.sbin.mysqld-instance.erb +++ b/cookbooks/mysql/templates/default/apparmor/usr.sbin.mysqld-instance.erb @@ -2,13 +2,12 @@ /etc/<%= @mysql_name %>/conf.d/ r, /etc/<%= @mysql_name %>/conf.d/* r, /etc/<%= @mysql_name %>/my.cnf r, -<%= @config.log_dir %>/ r, -<%= @config.log_dir %>/* rw, -<%= @config.data_dir %>/ r, -<%= @config.data_dir %>/** rwk, -<%= @config.run_dir %>/** rw, -<%= @config.pid_file %> rw, -<%= @config.socket_file %> rw, +<%= @log_dir %>/ r, +<%= @log_dir %>/* rw, +<%= @data_dir %>/ r, +<%= @data_dir %>/** rwk, +<%= @run_dir %>/** rw, +<%= @pid_file %> rw, +<%= @socket_file %> rw, /tmp/<%= @mysql_name %>/ r, /tmp/<%= @mysql_name %>/my.sql r, -<%= @config.tmp_dir %>/* rw, diff --git a/cookbooks/mysql/templates/default/apparmor/usr.sbin.mysqld.erb b/cookbooks/mysql/templates/default/apparmor/usr.sbin.mysqld.erb index 19ddbf5..3e1f1b0 100644 --- a/cookbooks/mysql/templates/default/apparmor/usr.sbin.mysqld.erb +++ b/cookbooks/mysql/templates/default/apparmor/usr.sbin.mysqld.erb @@ -35,10 +35,8 @@ /var/log/mysql/* rw, /var/run/mysqld/mysqld.pid rw, /var/run/mysqld/mysqld.sock w, - /var/run/mysqld/mysqld.sock.lock rw, /run/mysqld/mysqld.pid rw, /run/mysqld/mysqld.sock w, - /run/mysqld/mysqld.sock.lock rw, /sys/devices/system/cpu/ r, diff --git a/cookbooks/mysql/templates/default/my.cnf.erb b/cookbooks/mysql/templates/default/my.cnf.erb index ff10156..faa8d3e 100644 --- a/cookbooks/mysql/templates/default/my.cnf.erb +++ b/cookbooks/mysql/templates/default/my.cnf.erb @@ -7,8 +7,8 @@ default-character-set = <%= @config.charset %> <% if @config.port %> port = <%= @config.port %> <% end %> -<% if @config.socket_file %> -socket = <%= @config.socket_file %> +<% if @socket_file %> +socket = <%= @socket_file %> <% end %> [mysql] @@ -20,11 +20,11 @@ default-character-set = <%= @config.charset %> <% if @config.run_user %> user = <%= @config.run_user %> <% end %> -<% if @config.pid_file %> -pid-file = <%= @config.pid_file %> +<% if @pid_file %> +pid-file = <%= @pid_file %> <% end %> -<% if @config.socket_file %> -socket = <%= @config.socket_file %> +<% if @socket_file %> +socket = <%= @socket_file %> <% end %> <% if @config.bind_address %> bind-address = <%= @config.bind_address %> @@ -32,26 +32,26 @@ bind-address = <%= @config.bind_address %> <% if @config.port %> port = <%= @config.port %> <% end %> -<% if @config.data_dir %> -datadir = <%= @config.data_dir %> +<% if @data_dir %> +datadir = <%= @data_dir %> <% end %> -<% if @config.tmp_dir %> -tmpdir = <%= @config.tmp_dir %> +<% if @tmp_dir %> +tmpdir = <%= @tmp_dir %> <% end %> <% @config.mysqld_options.each do |option,value| %> <%= option %> = <%= value %> <% end %> -<% if @config.lc_messages_dir %> -lc-messages-dir = <%= @config.lc_messages_dir %> +<% if @lc_messages_dir %> +lc-messages-dir = <%= @lc_messages_dir %> <% end %> -<% if @config.error_log %> -log-error = <%= @config.error_log %> +<% if @error_log %> +log-error = <%= @error_log %> <% end %> -<% if @config.include_dir %> -!includedir <%= @config.include_dir %> +<% if @include_dir %> +!includedir <%= @include_dir %> <% end %> [mysqld_safe] -<% if @config.socket_file %> -socket = <%= @config.socket_file %> +<% if @socket_file %> +socket = <%= @socket_file %> <% end %> diff --git a/cookbooks/mysql2_chef_gem/CHANGELOG.md b/cookbooks/mysql2_chef_gem/CHANGELOG.md index aa192b0..a4f6d35 100644 --- a/cookbooks/mysql2_chef_gem/CHANGELOG.md +++ b/cookbooks/mysql2_chef_gem/CHANGELOG.md @@ -1,22 +1,5 @@ # mysql2_chef_gem CHANGELOG -## 2.0.1 (2017-03-28) - -- Include usage examples for installing on a mariadb server and included a note in the readme regarding the 2.0 changes. - -## 2.0.0 (2017-03-28) - -- Converted the previously HWRP resources/providers to a custom resource. This changes the behavior of choosing to install on mysql or mariadb in a breaking way. Instead of specifying the providers you need to call the resources directly. Specifying mysql2_chef_gem will default to mysql, but using mariadb will require using the mysql2_chef_gem_mariadb resource directly. -- Increase the minimum chef version to 12.5 -- Require mysql cookbook 8.2+ and build-essential cookbook 2.4+ -- Install the 0.4.5 gem by default -- Expand test recipe to cover more scenarios -- Switched testing to use Delivery local mode -- Switched from kitchen-docker to kitchen-dokken and removed testing for CentOS 5 / Ubuntu 12.04 as these are both going EOL -- Switched from Rubocop to cookstyle for linting -- Removed yum/apt from the Berksfile -- Remove test dependencies from the Gemfile and instead use ChefDK for testing - ## 1.1.0 (2016-04-27) - Added a chefignore file diff --git a/cookbooks/mysql2_chef_gem/README.md b/cookbooks/mysql2_chef_gem/README.md index e294bba..32e198b 100644 --- a/cookbooks/mysql2_chef_gem/README.md +++ b/cookbooks/mysql2_chef_gem/README.md @@ -1,20 +1,30 @@ -# Mysql2 Chef Gem Installer Cookbook +Mysql2 Chef Gem Installer Cookbook +================================== -[![Build Status](https://travis-ci.org/sinfomicien/mysql2_chef_gem.svg)](https://travis-ci.org/sinfomicien/mysql2_chef_gem) [![Cookbook Version](http://img.shields.io/cookbook/v/mysql2_chef_gem.svg)](https://supermarket.chef.io/cookbooks/mysql2_chef_gem) +[![Build Status](https://travis-ci.org/sinfomicien/mysql2_chef_gem.svg)](https://travis-ci.org/sinfomicien/mysql2_chef_gem) +[![Cookbook Version](http://img.shields.io/cookbook/v/mysql2_chef_gem.svg)](https://supermarket.chef.io/cookbooks/mysql2_chef_gem) -mysql2_chef_gem is a library cookbook that provides a resource for installing the mysql2 gem against either mysql or mariadb depending on usage. +mysql2_chef_gem is a library cookbook that provides an LWRP for use +in recipes. It provides a wrapper around `chef_gem` called +`mysql2_chef_gem` that eases the installation process, collecting the +prerequisites and side-stepping the compilation phase arms race. -## Scope +Scope +----- +This cookbook is concerned with the installation of the `mysql2` +Rubygem into Chef's gem path. Installation into other Ruby +environments, or installation of related gems such as `mysql` are +outside the scope of this cookbook. -This cookbook is concerned with the installation of the `mysql2` Rubygem into Chef's gem path. Installation into other Ruby environments, or installation of related gems such as `mysql` are outside the scope of this cookbook. +Requirements +------------ +* Chef 11 or higher +* Ruby 1.9 (preferably from the Chef full-stack installer) -## Requirements - -- Chef 12.5+ - -## Platform Support - -The following platforms have been tested with Test Kitchen and are known to work. +Platform Support +---------------- +The following platforms have been tested with Test Kitchen and are +known to work. ``` |---------------------------------------+-----+-----+-----+-----+-----| @@ -26,24 +36,27 @@ The following platforms have been tested with Test Kitchen and are known to work |---------------------------------------+-----+-----+-----+-----+-----| | Mysql2ChefGem::Mysql / centos-7 | | | X | X | X | |---------------------------------------+-----+-----+-----+-----+-----| -| Mysql2ChefGem::Mysql / fedora | | | X | X | X | +| Mysql2ChefGem::Mysql / fedora-20 | | | X | X | X | |---------------------------------------+-----+-----+-----+-----+-----| | Mysql2ChefGem::Mysql / debian-7 | | | X | | | |---------------------------------------+-----+-----+-----+-----+-----| +| Mysql2ChefGem::Mysql / ubuntu-10.04 | | X | | | | +|---------------------------------------+-----+-----+-----+-----+-----| +| Mysql2ChefGem::Mysql / ubuntu-12.04 | | | X | | | +|---------------------------------------+-----+-----+-----+-----+-----| | Mysql2ChefGem::Mysql / ubuntu-14.04 | | | X | X | | |---------------------------------------+-----+-----+-----+-----+-----| -| Mysql2ChefGem::Mariadb / fedora | | | X | | | +| Mysql2ChefGem::Mariadb / fedora-20 | | | X | | | |---------------------------------------+-----+-----+-----+-----+-----| | Mysql2ChefGem::Mariadb / ubuntu-14.04 | | | X | | | |---------------------------------------+-----+-----+-----+-----+-----| ``` -## Usage - +Usage +----- Place a dependency on the mysql cookbook in your cookbook's metadata.rb - ```ruby -depends 'mysql2_chef_gem' +depends 'mysql2_chef_gem', '~> 1.0' ``` Then, in a recipe: @@ -54,50 +67,47 @@ mysql2_chef_gem 'default' do end ``` -### 2.0 Compatibility - -In order to ensure compatibility with Chef 13, the 2.0 release of this cookbook changed the method used to specify installation against mariadb. Instead of specifying the underlying provider, you instead reference the mariadb specific resource. See the example below for the new syntax. - -## Resources Overview - +Resources Overview +------------------ ### mysql2_chef_gem -The `mysql2_chef_gem` resource installs mysql client development dependencies and installs the `mysql2` rubygem into Chef's Ruby environment. +The `mysql2_chef_gem` resource the build dependencies and installation +of the `mysql2` rubygem into Chef's Ruby environment #### Example - ```ruby mysql2_chef_gem 'default' do - gem_version '0.4.5' + gem_version '0.3.17' action :install end ``` - -#### Properties - -- `gem_version` - The version of the `mysql` Rubygem to install into the Chef environment. Defaults to '0.4.5' connector libraries -- `package_version` - The version of the mysql client libraries to install and link against +#### Parameters +- `gem_version` - The version of the `mysql` Rubygem to install into + the Chef environment. Defaults to '0.3.17' + connector libraries +- `client_version` - The version of the mysql client libraries to + install and link against #### Actions - - `:install` - Build and install the gem into the Chef environment - `:remove` - Delete the gem from the Chef environment -### mysql2_chef_gem_mariadb - -To install the mysql2 gem against an installation of mariadb reference the `mysql2_chef_gem_mariadb` resource directly. This resource includes all the same properties of the standard `mysql2_chef_gem` resource. +#### Providers +Chef selects a default provider based on platform and version, +but you can specify one if your platform support it. ```ruby -mysql2_chef_gem_mariadb 'default' do +mysql2_chef_gem 'default' do + provider Chef::Provider::Mysql2ChefGem::Mariadb action :install end ``` -## License & Authors -- Author:: Sean OMeara ([someara@sean.io](mailto:someara@sean.io)) -- Author:: Tim Smith ([tsmith@chef.io](mailto:tsmith@chef.io)) -- Author:: Nicolas Blanc([sinfomicien@gmail.com](mailto:sinfomicien@gmail.com)) +License & Authors +----------------- +- Author:: Sean OMeara () +- Author:: Nicolas Blanc() ``` Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/cookbooks/mysql2_chef_gem/libraries/provider_mysql2_chef_gem_mariadb.rb b/cookbooks/mysql2_chef_gem/libraries/provider_mysql2_chef_gem_mariadb.rb new file mode 100644 index 0000000..e25a427 --- /dev/null +++ b/cookbooks/mysql2_chef_gem/libraries/provider_mysql2_chef_gem_mariadb.rb @@ -0,0 +1,37 @@ +class Chef + class Provider + class Mysql2ChefGem + class Mariadb < Chef::Provider::LWRPBase + use_inline_resources if defined?(use_inline_resources) + + def whyrun_supported? + true + end + + action :install do + recipe_eval do + run_context.include_recipe 'build-essential::default' + end + + # As a recipe: must rely on global node attributes + recipe_eval do + run_context.include_recipe 'mariadb::client' + end + + gem_package 'mysql2' do + gem_binary RbConfig::CONFIG['bindir'] + '/gem' + version new_resource.gem_version + action :install + end + end + + action :remove do + gem_package 'mysql2' do + gem_binary RbConfig::CONFIG['bindir'] + '/gem' + action :remove + end + end + end + end + end +end diff --git a/cookbooks/mysql2_chef_gem/libraries/provider_mysql2_chef_gem_mysql.rb b/cookbooks/mysql2_chef_gem/libraries/provider_mysql2_chef_gem_mysql.rb new file mode 100644 index 0000000..cc1bace --- /dev/null +++ b/cookbooks/mysql2_chef_gem/libraries/provider_mysql2_chef_gem_mysql.rb @@ -0,0 +1,37 @@ +class Chef + class Provider + class Mysql2ChefGem + class Mysql < Chef::Provider::LWRPBase + include Chef::DSL::IncludeRecipe + use_inline_resources if defined?(use_inline_resources) + + def whyrun_supported? + true + end + + action :install do + include_recipe 'build-essential::default' + + # As a resource: can pass version from calling recipe + mysql_client 'default' do + version new_resource.client_version + action :create + end + + gem_package 'mysql2' do + gem_binary RbConfig::CONFIG['bindir'] + '/gem' + version new_resource.gem_version + action :install + end + end + + action :remove do + gem_package 'mysql2' do + gem_binary RbConfig::CONFIG['bindir'] + '/gem' + action :remove + end + end + end + end + end +end diff --git a/cookbooks/mysql2_chef_gem/libraries/resource_mysql2_chef_gem.rb b/cookbooks/mysql2_chef_gem/libraries/resource_mysql2_chef_gem.rb new file mode 100644 index 0000000..92ba02f --- /dev/null +++ b/cookbooks/mysql2_chef_gem/libraries/resource_mysql2_chef_gem.rb @@ -0,0 +1,15 @@ +require 'chef/resource/lwrp_base' + +class Chef + class Resource + class Mysql2ChefGem < Chef::Resource::LWRPBase + self.resource_name = :mysql2_chef_gem + actions :install, :remove + default_action :install + + attribute :mysql2_chef_gem_name, kind_of: String, name_attribute: true, required: true + attribute :gem_version, kind_of: String, default: '0.3.17' + attribute :client_version, kind_of: String, default: nil + end + end +end diff --git a/cookbooks/mysql2_chef_gem/libraries/z_provider_mapping.rb b/cookbooks/mysql2_chef_gem/libraries/z_provider_mapping.rb new file mode 100644 index 0000000..bf0d7aa --- /dev/null +++ b/cookbooks/mysql2_chef_gem/libraries/z_provider_mapping.rb @@ -0,0 +1,17 @@ +######### +# mysql2_chef_gem +######### +Chef::Platform.set platform: :amazon, resource: :mysql2_chef_gem, provider: Chef::Provider::Mysql2ChefGem::Mysql +Chef::Platform.set platform: :centos, version: '< 7.0', resource: :mysql2_chef_gem, provider: Chef::Provider::Mysql2ChefGem::Mysql +Chef::Platform.set platform: :centos, version: '>= 7.0', resource: :mysql2_chef_gem, provider: Chef::Provider::Mysql2ChefGem::Mysql +Chef::Platform.set platform: :debian, resource: :mysql2_chef_gem, provider: Chef::Provider::Mysql2ChefGem::Mysql +Chef::Platform.set platform: :fedora, version: '< 19', resource: :mysql2_chef_gem, provider: Chef::Provider::Mysql2ChefGem::Mysql +Chef::Platform.set platform: :fedora, version: '>= 19', resource: :mysql2_chef_gem, provider: Chef::Provider::Mysql2ChefGem::Mysql +Chef::Platform.set platform: :omnios, resource: :mysql2_chef_gem, provider: Chef::Provider::Mysql2ChefGem::Mysql +Chef::Platform.set platform: :redhat, version: '< 7.0', resource: :mysql2_chef_gem, provider: Chef::Provider::Mysql2ChefGem::Mysql +Chef::Platform.set platform: :redhat, version: '>= 7.0', resource: :mysql2_chef_gem, provider: Chef::Provider::Mysql2ChefGem::Mysql +Chef::Platform.set platform: :scientific, version: '< 7.0', resource: :mysql2_chef_gem, provider: Chef::Provider::Mysql2ChefGem::Mysql +Chef::Platform.set platform: :scientific, version: '>= 7.0', resource: :mysql2_chef_gem, provider: Chef::Provider::Mysql2ChefGem::Mysql +Chef::Platform.set platform: :smartos, resource: :mysql2_chef_gem, provider: Chef::Provider::Mysql2ChefGem::Mysql +Chef::Platform.set platform: :suse, resource: :mysql2_chef_gem, provider: Chef::Provider::Mysql2ChefGem::Mysql +Chef::Platform.set platform: :ubuntu, resource: :mysql2_chef_gem, provider: Chef::Provider::Mysql2ChefGem::Mysql diff --git a/cookbooks/mysql2_chef_gem/metadata.json b/cookbooks/mysql2_chef_gem/metadata.json index 8144cd2..67e67fa 100644 --- a/cookbooks/mysql2_chef_gem/metadata.json +++ b/cookbooks/mysql2_chef_gem/metadata.json @@ -1 +1 @@ -{"name":"mysql2_chef_gem","version":"2.0.1","description":"Provides the mysql2_chef_gem resource","long_description":"# Mysql2 Chef Gem Installer Cookbook\n\n[![Build Status](https://travis-ci.org/sinfomicien/mysql2_chef_gem.svg)](https://travis-ci.org/sinfomicien/mysql2_chef_gem) [![Cookbook Version](http://img.shields.io/cookbook/v/mysql2_chef_gem.svg)](https://supermarket.chef.io/cookbooks/mysql2_chef_gem)\n\nmysql2_chef_gem is a library cookbook that provides a resource for installing the mysql2 gem against either mysql or mariadb depending on usage.\n\n## Scope\n\nThis cookbook is concerned with the installation of the `mysql2` Rubygem into Chef's gem path. Installation into other Ruby environments, or installation of related gems such as `mysql` are outside the scope of this cookbook.\n\n## Requirements\n\n- Chef 12.5+\n\n## Platform Support\n\nThe following platforms have been tested with Test Kitchen and are known to work.\n\n```\n|---------------------------------------+-----+-----+-----+-----+-----|\n| | 5.0 | 5.1 | 5.5 | 5.6 | 5.7 |\n|---------------------------------------+-----+-----+-----+-----+-----|\n| Mysql2ChefGem::Mysql / centos-5 | X | | | X | X |\n|---------------------------------------+-----+-----+-----+-----+-----|\n| Mysql2ChefGem::Mysql / centos-6 | | X | X | X | X |\n|---------------------------------------+-----+-----+-----+-----+-----|\n| Mysql2ChefGem::Mysql / centos-7 | | | X | X | X |\n|---------------------------------------+-----+-----+-----+-----+-----|\n| Mysql2ChefGem::Mysql / fedora | | | X | X | X |\n|---------------------------------------+-----+-----+-----+-----+-----|\n| Mysql2ChefGem::Mysql / debian-7 | | | X | | |\n|---------------------------------------+-----+-----+-----+-----+-----|\n| Mysql2ChefGem::Mysql / ubuntu-14.04 | | | X | X | |\n|---------------------------------------+-----+-----+-----+-----+-----|\n| Mysql2ChefGem::Mariadb / fedora | | | X | | |\n|---------------------------------------+-----+-----+-----+-----+-----|\n| Mysql2ChefGem::Mariadb / ubuntu-14.04 | | | X | | |\n|---------------------------------------+-----+-----+-----+-----+-----|\n```\n\n## Usage\n\nPlace a dependency on the mysql cookbook in your cookbook's metadata.rb\n\n```ruby\ndepends 'mysql2_chef_gem'\n```\n\nThen, in a recipe:\n\n```ruby\nmysql2_chef_gem 'default' do\n action :install\nend\n```\n\n### 2.0 Compatibility\n\nIn order to ensure compatibility with Chef 13, the 2.0 release of this cookbook changed the method used to specify installation against mariadb. Instead of specifying the underlying provider, you instead reference the mariadb specific resource. See the example below for the new syntax.\n\n## Resources Overview\n\n### mysql2_chef_gem\n\nThe `mysql2_chef_gem` resource installs mysql client development dependencies and installs the `mysql2` rubygem into Chef's Ruby environment.\n\n#### Example\n\n```ruby\nmysql2_chef_gem 'default' do\n gem_version '0.4.5'\n action :install\nend\n```\n\n#### Properties\n\n- `gem_version` - The version of the `mysql` Rubygem to install into the Chef environment. Defaults to '0.4.5' connector libraries\n- `package_version` - The version of the mysql client libraries to install and link against\n\n#### Actions\n\n- `:install` - Build and install the gem into the Chef environment\n- `:remove` - Delete the gem from the Chef environment\n\n### mysql2_chef_gem_mariadb\n\nTo install the mysql2 gem against an installation of mariadb reference the `mysql2_chef_gem_mariadb` resource directly. This resource includes all the same properties of the standard `mysql2_chef_gem` resource.\n\n```ruby\nmysql2_chef_gem_mariadb 'default' do\n action :install\nend\n```\n\n## License & Authors\n\n- Author:: Sean OMeara ([someara@sean.io](mailto:someara@sean.io))\n- Author:: Tim Smith ([tsmith@chef.io](mailto:tsmith@chef.io))\n- Author:: Nicolas Blanc([sinfomicien@gmail.com](mailto:sinfomicien@gmail.com))\n\n```\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```\n","maintainer":"Nicolas Blanc","maintainer_email":"sinfomicien@gmail.com","license":"Apache 2.0","platforms":{"centos":">= 0.0.0","redhat":">= 0.0.0","scientific":">= 0.0.0","oracle":">= 0.0.0","fedora":">= 0.0.0","debian":">= 0.0.0","ubuntu":">= 0.0.0"},"dependencies":{"build-essential":">= 2.4.0","mysql":">= 8.2.0","mariadb":">= 0.0.0"},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{},"source_url":"https://github.com/sinfomicien/mysql2_chef_gem","issues_url":"https://github.com/sinfomicien/mysql2_chef_gem/issues","chef_version":">= 12.5","ohai_version":{}} \ No newline at end of file +{"name":"mysql2_chef_gem","version":"1.1.0","description":"Provides the mysql2_chef_gem resource","long_description":"Mysql2 Chef Gem Installer Cookbook\n==================================\n\n[![Build Status](https://travis-ci.org/sinfomicien/mysql2_chef_gem.svg)](https://travis-ci.org/sinfomicien/mysql2_chef_gem)\n[![Cookbook Version](http://img.shields.io/cookbook/v/mysql2_chef_gem.svg)](https://supermarket.chef.io/cookbooks/mysql2_chef_gem)\n\nmysql2_chef_gem is a library cookbook that provides an LWRP for use\nin recipes. It provides a wrapper around `chef_gem` called\n`mysql2_chef_gem` that eases the installation process, collecting the\nprerequisites and side-stepping the compilation phase arms race.\n\nScope\n-----\nThis cookbook is concerned with the installation of the `mysql2`\nRubygem into Chef's gem path. Installation into other Ruby\nenvironments, or installation of related gems such as `mysql` are\noutside the scope of this cookbook.\n\nRequirements\n------------\n* Chef 11 or higher\n* Ruby 1.9 (preferably from the Chef full-stack installer)\n\nPlatform Support\n----------------\nThe following platforms have been tested with Test Kitchen and are\nknown to work.\n\n```\n|---------------------------------------+-----+-----+-----+-----+-----|\n| | 5.0 | 5.1 | 5.5 | 5.6 | 5.7 |\n|---------------------------------------+-----+-----+-----+-----+-----|\n| Mysql2ChefGem::Mysql / centos-5 | X | | | X | X |\n|---------------------------------------+-----+-----+-----+-----+-----|\n| Mysql2ChefGem::Mysql / centos-6 | | X | X | X | X |\n|---------------------------------------+-----+-----+-----+-----+-----|\n| Mysql2ChefGem::Mysql / centos-7 | | | X | X | X |\n|---------------------------------------+-----+-----+-----+-----+-----|\n| Mysql2ChefGem::Mysql / fedora-20 | | | X | X | X |\n|---------------------------------------+-----+-----+-----+-----+-----|\n| Mysql2ChefGem::Mysql / debian-7 | | | X | | |\n|---------------------------------------+-----+-----+-----+-----+-----|\n| Mysql2ChefGem::Mysql / ubuntu-10.04 | | X | | | |\n|---------------------------------------+-----+-----+-----+-----+-----|\n| Mysql2ChefGem::Mysql / ubuntu-12.04 | | | X | | |\n|---------------------------------------+-----+-----+-----+-----+-----|\n| Mysql2ChefGem::Mysql / ubuntu-14.04 | | | X | X | |\n|---------------------------------------+-----+-----+-----+-----+-----|\n| Mysql2ChefGem::Mariadb / fedora-20 | | | X | | |\n|---------------------------------------+-----+-----+-----+-----+-----|\n| Mysql2ChefGem::Mariadb / ubuntu-14.04 | | | X | | |\n|---------------------------------------+-----+-----+-----+-----+-----|\n```\n\nUsage\n-----\nPlace a dependency on the mysql cookbook in your cookbook's metadata.rb\n```ruby\ndepends 'mysql2_chef_gem', '~> 1.0'\n```\n\nThen, in a recipe:\n\n```ruby\nmysql2_chef_gem 'default' do\n action :install\nend\n```\n\nResources Overview\n------------------\n### mysql2_chef_gem\n\nThe `mysql2_chef_gem` resource the build dependencies and installation\nof the `mysql2` rubygem into Chef's Ruby environment\n\n#### Example\n```ruby\nmysql2_chef_gem 'default' do\n gem_version '0.3.17'\n action :install\nend\n```\n#### Parameters\n- `gem_version` - The version of the `mysql` Rubygem to install into\n the Chef environment. Defaults to '0.3.17'\n connector libraries\n- `client_version` - The version of the mysql client libraries to\n install and link against\n\n#### Actions\n- `:install` - Build and install the gem into the Chef environment\n- `:remove` - Delete the gem from the Chef environment\n\n#### Providers\nChef selects a default provider based on platform and version,\nbut you can specify one if your platform support it.\n\n```ruby\nmysql2_chef_gem 'default' do\n provider Chef::Provider::Mysql2ChefGem::Mariadb\n action :install\nend\n```\n\n\nLicense & Authors\n-----------------\n- Author:: Sean OMeara ()\n- Author:: Nicolas Blanc()\n\n```\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```\n","maintainer":"Nicolas Blanc","maintainer_email":"sinfomicien@gmail.com","license":"Apache 2.0","platforms":{"amazon":">= 0.0.0","redhat":">= 0.0.0","centos":">= 0.0.0","scientific":">= 0.0.0","fedora":">= 0.0.0","debian":">= 0.0.0","ubuntu":">= 0.0.0","oracle":">= 0.0.0"},"dependencies":{"build-essential":">= 0.0.0","mysql":">= 6.0","mariadb":">= 0.0.0"},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{}} \ No newline at end of file diff --git a/cookbooks/mysql2_chef_gem/resources/mysql2_chef_gem_mariadb.rb b/cookbooks/mysql2_chef_gem/resources/mysql2_chef_gem_mariadb.rb deleted file mode 100644 index 60ab5b2..0000000 --- a/cookbooks/mysql2_chef_gem/resources/mysql2_chef_gem_mariadb.rb +++ /dev/null @@ -1,29 +0,0 @@ -property :mysql2_chef_gem_name, String, name_attribute: true, required: true -property :gem_version, String, default: '0.4.5' -property :package_version, String - -provides :mysql2_chef_gem_mariadb - -action :install do - recipe_eval do - run_context.include_recipe 'build-essential::default' - end - - # As a recipe: must rely on global node attributes - recipe_eval do - run_context.include_recipe 'mariadb::client' - end - - gem_package 'mysql2' do - gem_binary RbConfig::CONFIG['bindir'] + '/gem' - version new_resource.gem_version - action :install - end -end - -action :remove do - gem_package 'mysql2' do - gem_binary RbConfig::CONFIG['bindir'] + '/gem' - action :remove - end -end diff --git a/cookbooks/mysql2_chef_gem/resources/mysql2_chef_gem_mysql.rb b/cookbooks/mysql2_chef_gem/resources/mysql2_chef_gem_mysql.rb deleted file mode 100644 index 28dd390..0000000 --- a/cookbooks/mysql2_chef_gem/resources/mysql2_chef_gem_mysql.rb +++ /dev/null @@ -1,29 +0,0 @@ -property :mysql2_chef_gem_name, String, name_attribute: true, required: true -property :gem_version, String, default: '0.4.5' -property :package_version, String - -provides :mysql2_chef_gem -provides :mysql2_chef_gem_mysql - -action :install do - include_recipe 'build-essential::default' - - # As a resource: can pass version from calling recipe - mysql_client 'default' do - version new_resource.package_version if new_resource.package_version - action :create - end - - gem_package 'mysql2' do - gem_binary RbConfig::CONFIG['bindir'] + '/gem' - version new_resource.gem_version - action :install - end -end - -action :remove do - gem_package 'mysql2' do - gem_binary RbConfig::CONFIG['bindir'] + '/gem' - action :remove - end -end diff --git a/cookbooks/rbac/README.md b/cookbooks/rbac/README.md new file mode 100644 index 0000000..e7f3f74 --- /dev/null +++ b/cookbooks/rbac/README.md @@ -0,0 +1,82 @@ +Role based access control +========================= + +Solaris and Illumos provide sophisticated role-based access control for +delegating authorizations within the system. Using RBAC, users can be +given permissions to manage and update services without sudo. + +This cookbook provides chef with LWRPs to manage RBAC and grant permissions. + +At this time this cookbook ONLY manages SMF-related permissions (ie, ability +of non-priviliged users to start/stop SMF services), but in the future it may +be enhanced to support arbitrary Solaris permissions. + +## Installation + +In order to add the RBAC LWRPs to a chef run, add the following recipe +to the run_list: + + rbac::default + +This will do no work, but will load the providers. + +## LWRPs + +### rbac + +Defines a set of authorizations that can be applied to SMF services and +authorized to users, without actually applying them to users. + +Actions: + * create (default) + +Attributes: + * name + +Example: + +```ruby +rbac "nginx" do + action :create +end +``` + +This will update the authorizations file at `/etc/security/auth_attr` +with the following lines: + +``` +solaris.smf.manage.nginx:::Manage nginx Service States:: +solaris.smf.value.nginx:::Change value of nginx Service:: +``` + +Users who are given these authorizations can change properties of the +service as well as change its state (i.e. `svcadm disable|enable|restart|clear service` + +### rbac_auth + +Adds the rbac definition created by `auth` to the user `name`. + +Actions: + * add (default) + +Attributes: + * name - for descriptive purposes and to ensure that each LWRP call is uniquely + identified in the chef run + * user + * auth + +Example: + +```ruby +rbac_auth "add nginx management permissions to my_user" do + user "my_user" + auth "nginx" +end +``` + +This adds both manage and value auths to user `my_user`. + +## TODO + +* separate manage auth from value auth +* ability to delete all rbac attributes diff --git a/cookbooks/rbac/libraries/rbac.rb b/cookbooks/rbac/libraries/rbac.rb new file mode 100644 index 0000000..27b29a8 --- /dev/null +++ b/cookbooks/rbac/libraries/rbac.rb @@ -0,0 +1,15 @@ +# This module is used to retain state during the course of a chef +# run. The LWRPs in the cookbook modify a global hash in this module, +# and at the end of the chef run if user authorizations change they +# are written out into the system. +# +module RBAC + def self.authorizations + @authorizations ||= {} + end + + def self.add_authorization(username, auth) + authorizations[username] ||= [] + authorizations[username] << auth + end +end diff --git a/cookbooks/rbac/metadata.json b/cookbooks/rbac/metadata.json new file mode 100644 index 0000000..08c1d91 --- /dev/null +++ b/cookbooks/rbac/metadata.json @@ -0,0 +1,42 @@ +{ + "name": "rbac", + "description": "Allows delegation of service management to users with Solaris Role Based Access Control (RBAC)", + "long_description": "Role based access control\n=========================\n\nSolaris and Illumos provide sophisticated role-based access control for\ndelegating authorizations within the system. Using RBAC, users can be\ngiven permissions to manage and update services without sudo.\n\nThis cookbook provides chef with LWRPs to manage RBAC and grant permissions.\n\nAt this time this cookbook ONLY manages SMF-related permissions (ie, ability\nof non-priviliged users to start/stop SMF services), but in the future it may\nbe enhanced to support arbitrary Solaris permissions.\n\n## Installation\n\nIn order to add the RBAC LWRPs to a chef run, add the following recipe \nto the run_list:\n\n rbac::default\n\nThis will do no work, but will load the providers.\n\n## LWRPs\n\n### rbac\n\nDefines a set of authorizations that can be applied to SMF services and\nauthorized to users, without actually applying them to users.\n\nActions:\n * create (default)\n\nAttributes:\n * name\n\nExample:\n\n```ruby\nrbac \"nginx\" do\n action :create\nend\n```\n\nThis will update the authorizations file at `/etc/security/auth_attr`\nwith the following lines:\n\n```\nsolaris.smf.manage.nginx:::Manage nginx Service States::\nsolaris.smf.value.nginx:::Change value of nginx Service::\n```\n\nUsers who are given these authorizations can change properties of the\nservice as well as change its state (i.e. `svcadm disable|enable|restart|clear service`\n\n### rbac_auth\n\nAdds the rbac definition created by `auth` to the user `name`.\n\nActions:\n * add (default)\n\nAttributes:\n * name - for descriptive purposes and to ensure that each LWRP call is uniquely\n identified in the chef run\n * user\n * auth\n\nExample:\n\n```ruby\nrbac_auth \"add nginx management permissions to my_user\" do\n user \"my_user\"\n auth \"nginx\"\nend\n```\n\nThis adds both manage and value auths to user `my_user`.\n\n## TODO\n\n* separate manage auth from value auth\n* ability to delete all rbac attributes\n", + "maintainer": "Eric Saxby", + "maintainer_email": "sax@livinginthepast.org", + "license": "MIT", + "platforms": { + "solaris2": ">= 0.0.0", + "smartos": ">= 0.0.0" + }, + "dependencies": { + + }, + "recommendations": { + + }, + "suggestions": { + + }, + "conflicting": { + + }, + "providing": { + + }, + "replacing": { + + }, + "attributes": { + + }, + "groupings": { + + }, + "recipes": { + + }, + "version": "1.0.3", + "source_url": "", + "issues_url": "" +} diff --git a/cookbooks/rbac/metadata.rb b/cookbooks/rbac/metadata.rb new file mode 100644 index 0000000..91c58d2 --- /dev/null +++ b/cookbooks/rbac/metadata.rb @@ -0,0 +1,10 @@ +name 'rbac' +maintainer 'Eric Saxby' +maintainer_email 'sax@livinginthepast.org' +license 'MIT' +description 'Allows delegation of service management to users with Solaris Role Based Access Control (RBAC)' +long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) +version '1.0.3' + +supports 'solaris2' +supports 'smartos' diff --git a/cookbooks/rbac/providers/auth.rb b/cookbooks/rbac/providers/auth.rb new file mode 100644 index 0000000..d922489 --- /dev/null +++ b/cookbooks/rbac/providers/auth.rb @@ -0,0 +1,20 @@ +def load_current_resource + @current_resource = Chef::Resource::RbacAuth.new(new_resource.name) + @new_resource.definition = run_context.resource_collection.find(:rbac => @new_resource.auth) + begin + @new_resource.user_definition = run_context.resource_collection.find(:rbac_user => @new_resource.user) + rescue Chef::Exceptions::ResourceNotFound + end +end + +action :add do + unless new_resource.user_definition + new_resource.user_definition = rbac_user new_resource.user + end + + new_resource.add_auth new_resource.user, new_resource.auth + + new_resource.updated_by_last_action(true) + + new_resource.notifies(:apply, new_resource.user_definition, :delayed) +end diff --git a/cookbooks/rbac/providers/default.rb b/cookbooks/rbac/providers/default.rb new file mode 100644 index 0000000..368de9e --- /dev/null +++ b/cookbooks/rbac/providers/default.rb @@ -0,0 +1,27 @@ + +def load_current_resource + @current_resource = Chef::Resource::Rbac.new(@new_resource.name) +end + +action :create do + definition = new_resource.name + + new_resource.updated_by_last_action(false) + + manage_auth = "solaris.smf.manage.#{definition}:::Manage #{definition} Service States::" + manage = execute "add RBAC #{definition} management to /etc/security/auth_attr" do + command "echo \"#{manage_auth}\" >> /etc/security/auth_attr" + not_if "grep \"#{manage_auth}\" /etc/security/auth_attr" + end + + # This additional permission allows the user to call svccfg -s service setprop + # to set dynamic properties without having to re-run chef. This may be + # moved into a separate LWRP in the future. + value_auth = "solaris.smf.value.#{definition}:::Change value of #{definition} Service::" + value = execute "add RBAC #{definition} value to /etc/security/auth_attr" do + command "echo \"#{value_auth}\" >> /etc/security/auth_attr" + not_if "grep \"#{value_auth}\" /etc/security/auth_attr" + end + + new_resource.updated_by_last_action(manage.updated_by_last_action? || value.updated_by_last_action?) +end diff --git a/cookbooks/rbac/providers/user.rb b/cookbooks/rbac/providers/user.rb new file mode 100644 index 0000000..cefb660 --- /dev/null +++ b/cookbooks/rbac/providers/user.rb @@ -0,0 +1,22 @@ +# The rbac_user LWRP is an internal set of classes used by other LWRPs to +# delay writing of user attributes until the end of the chef run. It should not be +# manually run. + +def load_current_resource + @current_resource = Chef::Resource::Rbac::User.new(@new_resource.user) +end + +action :apply do + username = new_resource.user + + auths = RBAC.authorizations[username] + permissions = auths.inject([]) do |auth, name| + auth + ["solaris.smf.manage.#{name}", "solaris.smf.value.#{name}"] + end.sort.uniq.join(',') + + execute "Apply rbac authorizations to #{username}" do + command "usermod -A #{permissions} #{username}" + action :nothing + not_if "grep #{username} /etc/user_attr | grep 'auths=#{permissions}'" + end.run_action(:run) +end diff --git a/cookbooks/rbac/recipes/default.rb b/cookbooks/rbac/recipes/default.rb new file mode 100644 index 0000000..3cab4b3 --- /dev/null +++ b/cookbooks/rbac/recipes/default.rb @@ -0,0 +1,6 @@ +# +# Cookbook Name:: rbac +# Recipe:: default +# +# Copyright 2012, ModCloth, Inc. +# diff --git a/cookbooks/rbac/resources/auth.rb b/cookbooks/rbac/resources/auth.rb new file mode 100644 index 0000000..4c8bedd --- /dev/null +++ b/cookbooks/rbac/resources/auth.rb @@ -0,0 +1,14 @@ + +default_action :add + +actions :add + +attribute :user, :kind_of => String, :required => true +attribute :auth, :kind_of => String, :required => true + +# private, internal attributes +attr_accessor :definition, :user_definition + +def add_auth(user, auth) + RBAC.add_authorization(user, auth) +end diff --git a/cookbooks/rbac/resources/default.rb b/cookbooks/rbac/resources/default.rb new file mode 100644 index 0000000..8a56e0a --- /dev/null +++ b/cookbooks/rbac/resources/default.rb @@ -0,0 +1,6 @@ + +default_action :create + +actions :create + +attribute :name, :kind_of => String, :name_attribute => true, :required => true diff --git a/cookbooks/rbac/resources/user.rb b/cookbooks/rbac/resources/user.rb new file mode 100644 index 0000000..25fb93c --- /dev/null +++ b/cookbooks/rbac/resources/user.rb @@ -0,0 +1,6 @@ + +default_action :nothing + +actions :apply + +attribute :user, :kind_of => String, :name_attribute => true, :required => true diff --git a/cookbooks/smf/README.md b/cookbooks/smf/README.md new file mode 100644 index 0000000..a1dabb0 --- /dev/null +++ b/cookbooks/smf/README.md @@ -0,0 +1,370 @@ +SMF +=== + +## Description + +Service Management Facility (SMF) is a tool in many Illumos and Solaris-derived operating systems +that treats services as first class objects of the system. It provides an XML syntax for +declaring how the system can interact with and control a service. + +The SMF cookbook contains providers for creating or modifying a service within the SMF framework. + + +## Requirements + +Any operating system that uses SMF, ie Solaris, SmartOS, OpenIndiana etc. + +The `smf` provider depends on the `builder` gem, which can be installed +via the `smf::default` recipe. + +Requires the RBAC cookbook, which can be found at . + +Processes can be run inside a project wrapper. In this case, look to the Resource Control cookbook, +which can be found at . Note that the SMF LWRP +does not create or manage the project. + + +## Basic Usage + +Note that we run the `smf::default` recipe before using LWRPs from this +cookbook. + +```ruby +include_recipe 'smf' + +smf 'my-service' do + user 'non-root-user' + start_command 'my-service start' + start_timeout 10 + stop_command 'pkill my-service' + stop_timeout 5 + restart_command 'my-service restart' + restart_timeout 60 + environment 'PATH' => '/home/non-root-user/bin', + 'RAILS_ENV' => 'staging' + locale 'C' + manifest_type 'application' + service_path '/var/svc/manifest' + notifies :restart, 'service[my-service]' +end + +service 'my-service' do + action :enable +end + +service 'my-service' do + action :restart +end +``` + + +## Attributes + +Ownership: +* `user` - User to run service commands as +* `group` - Group to run service commands as + +RBAC +* `authorization` - What management and value authorizations should be + created for this service. Defaults to the service name. + +Dependency management: +* `include_default_dependencies` - Service should depend on file system + and network services. Defaults to `true`. See [Dependencies](#dependencies) + for more info. +* `dependency` - an optional array of hashes signifying service and path + dependencies for this service to run. See [Dependencies](#dependencies). + +Process management: +* `project` - Name of project to run commands in +* `start_command` +* `start_timeout` +* `stop_command` - defaults to `:kill`, which basically means it will destroy every PID generated from the start command +* `stop_timeout` +* `restart_command` - defaults to `stop_command`, then `start_command` +* `restart_timeout` +* `refresh_command` - by default SMF treats this as `true`. This will be called when the SMF definition changes or + when a `notify :reload, 'service[thing]'` is called. +* `refresh_timeout` +* `duration` - Can be either `contract`, `wait`, `transient` or + `child`, but defaults to `contract`. See the [Duration](#duration) section below. +* `environment` - Hash - Environment variables to set while running commands +* `ignore` - Array - Faults to ignore in subprocesses. For example, + if core dumps in children are handled by a master process and you + don't want SMF thinking the service is exploding, you can ignore + ["core", "signal"]. +* `privileges` - Array - An array of privileges to be allowed for started processes. + Defaults to ['basic', 'net_privaddr'] +* `property_groups` - Hash - This should be in the form `{"group name" => {"type" => "application", "key" => "value", ...}}` +* `working_directory` - PWD that SMF should cd to in order to run commands +* `locale` - Character encoding to use (default "C") + +Manifest/FMRI metadata: +* `service_path` - defaults to `/var/svc/manifest` +* `manifest_type` - defaults to `application` +* `stability` - String - defaults to "Evolving". Valid options are + "Standard", "Stable", "Evolving", "Unstable", "External" and + "Obsolete" + +Deprecated: +* `credentials_user` - deprecated in favor of `user` + + +## Provider Actions + +### :install (default) + +This will drop a manifest XML file into `#{service_path}/#{manifest_type}/#{name}.xml`. If there is already a service +with a name that is matched by `new_resource.name` then the FMRI of our manifest will be set to the FMRI of the +pre-existing service. In this case, our properties will be merged into the properties of the pre-existing service. + +In this way, updates to recipes that use the SMF provider will not delete existing service properties, but will add +or overwrite them. + +Because of this, the SMF provider can be used to update properties for +services that are installed via a package manager. + +### :delete + +Remove an SMF definition. This stops the service if it is running. + +### :add_rbac + +This uses the `rbac` cookbook to define permissions that can then be applied to a user. This can be useful when local +users should manage services that are added via packages. + +```ruby +smf "nginx" do + action :add_rbac +end + +rbac_auth "Allow my user to manage nginx" do + user "my_user" + auth "nginx" +end +``` + + +## Resource Notes + +### `user`, `working_directory` and `environment` + +SMF does a remarkably good job running services as delegated users, and removes a lot of pain if you configure a +service correctly. There are many examples online (blogs, etc) of users wrapping their services in shell scripts with +`start`, `stop`, `restart` arguments. In general it seems as if the intention of these scripts is to take care of the +problem of setting environment variables and shelling out as another user. + +The use of init scripts to wrap executables can be unnecessary with SMF, as it provides hooks for all of these use cases. +When using `user`, SMF will assume that the `working_directory` is the user's home directory. This can be +easily overwritten (to `/home/user/app/current` for a Rails application, for example). One thing to be careful of is +that shell profile files will not be loaded. For this reason, if environment variables (such as PATH) are different +on your system or require additional entries arbitrary key/values may be set using the `environment` attribute. + +All things considered, one should think carefully about the need for an init script when working with SMF. For +well-behaved applications with simple configuration, an init script is overkill. Applications with endless command-line +options or that need a real login shell (for instance ruby applications that use RVM) an init script may make life +easier. + +### Role Based Authorization + +By default the SMF definition creates authorizations based on the +service name. The service user is then granted these authorizations. If +the service is named `asplosions`, then `solaris.smf.manage.asplosions` +and `solaris.smf.value.asplosions` will be created. + +The authorization can be changed by manually setting `authorization` on +the smf block: + +```ruby +smf 'asplosions' do + user 'monkeyking' + start_command 'asplode' + authorization 'booms' +end +``` + +This can be helpful if there are many services configured on a single +host, as multiple services can be collapsed into the same +authorizations. For instance: https://illumos.org/issues/4968 + +### Dependencies + +SMF allows services to explicitly list their dependencies on other +services. Among other things, this ensures that services are enabled in +the proper order on boot, so that a service doesn't fail to start +because another service has not yet been started. + +By default, services created by the SMF LWRP depend on the following other services: +* svc:/milestone/sysconfig +* svc:/system/filesystem/local +* svc:/milestone/name-services +* svc:/milestone/network + +On Solaris11, `svc:/milestone/sysconfig` is replaced with +`svc:/milestone/config`. + +These are configured with the attribute `include_default_dependencies`, +which defaults to `true`. + +Other dependencies can be specified with the `dependencies` attribute, +which takes an array of hashes as follows: + +```ruby +smf 'redis' + +smf 'redis-6999' do + start_command "..." + dependencies [ + {name: 'redis', fmris: ['svc:/application/management/redis'], + grouping: 'require_all', restart_on: 'restart', type: 'service'} + ] +end +``` + +Valid options for grouping: +* require_all - All listed FMRIs must be online +* require_any - Any of the listed FMRIs must be online +* exclude_all - None of the listed FMRIs can be online +* optional_all - FMRIs are either online or unable to come online + +Valid options for restart_on: +* error - Hardware fault +* restart - Restarts service if the depedency is restarted +* refresh - Restarted if the dependency is restarted or refreshed for + any reason +* none - Don't do anything + +Valid options for type: +* service - expects dependency FMRIs to be other services ie: svc:/type/of/service:instance +* path - expects FMRIs to be paths, ie file://localhost/etc/redis/redis.conf + +Note: the provider currently does not do any validation of these values. Also, type:path has not been extensively +tested. Use this at your own risk, or improve the provider's compatibility with type:path and submit a pull request! + +### Duration + +There are several different ways that SMF can track your service. By default it uses `contract`. +Basically, this means that it will keep track of the PIDs of all daemonized processes generated from `start_command`. +If SMF sees that processes are cycling, it may try to restart the service. If things get too hectic, it +may think that your service is flailing and put it into maintenance mode. If this is normal for your service, +for instance if you have a master that occasionally reaps processes, you may want to specify additional +configuration options. + +If you have a job that you want managed by SMF, but which is not daemonized, another duration option is +`transient`. In this mode, SMF will not watch any processes, but will expect that the main process exits cleanly. +This can be used, for instance, for a script that must be run at boot time, or for a script that you want to delegate +to particular users with Role Based Access Control. In this case, the script can be registered with SMF to run as root, +but with the start_command delegated to your user. + +A third option is `wait`. This covers non-daemonized processes. + +A fourth option is `child`. + +### Ignore + +Sometimes you have a case where your service behaves poorly. The Ruby server Unicorn, for example, has a master +process that likes to kill its children. This causes core dumps that SMF will interpret to be a failing service. +Instead you can `ignore ["core", "signal"]` and SMF will stop caring about core dumps. + +### Privileges + +Some system calls require privileges generally only granted to superusers or particular roles. In Solaris, an +SMF definition can also set specific privileges for contracted processes. + +By default the SMF provider will grant 'basic' and 'net_privaddr' permissions, but this can be set as follows: + +```ruby +smf 'elasticsearch' do + start_command 'elasticsearch' + privileges ['basic', 'proc_lock_memory'] +end +``` + +See the (privileges man page)[https://www.illumos.org/man/5/privileges] for more information. + +### Property Groups + +Property Groups are where you can store extra information for SMF to use later. They should be used in the +following format: + +```ruby +smf "my-service" do + start_command "do-something" + property_groups({ + "config" => { + "type" => "application", + "my-property" => "property value" + } + }) +end +``` + +`type` will default to `application`, and is used in the manifest XML to declare how the property group will be +used. For this reason, `type` can not be used as a property name (ie variable). + +One way to use property groups is to pass variables on to commands, as follows: + +```ruby +rails_env = node["from-chef-environment"]["rails-env"] + +smf "unicorn" do + start_command "bundle exec unicorn_rails -c /home/app_user/app/current/config/%{config/rails_env} -E %{config/rails_env} -D" + start_timeout 300 + restart_command ":kill -SIGUSR2" + restart_timeout 300 + working_directory "/home/app_user/app/current" + property_groups({ + "config" => { + "rails_env" => rails_env + } + }) +end +``` + +This is especially handy if you have a case where your commands may come from role attributes, but can +only work if they have access to variables set in an environment or computed in a recipe. + +### Stability + +This is for reference more than anything, so that administrators of a service know what to expect of possible changes to +the service definition. + +See: + + +## Working Examples + +Please see the [examples](https://github.com/livinginthepast/smf/blob/master/EXAMPLES.md) page for +example usages. + + +## Cookbook upgrades, possible side effects + +Changes to this cookbook may change the way that its internal checksums are generated for a service. +If you `notify :restart` any service from within the `smf` block or include a `refresh_command`, please +be aware that upgrading this cookbook may trigger a refresh or a registered notification on the first +subsequent chef run. + +## Contributing + +* fork +* file an issue to track updates/communication +* add tests +* rebase master into your branch +* issue a pull request + +Please do not increment the cookbook version in a fork. Version updates +will be done on the master branch after any pull requests are merged. + +When upstream changes are added to the master branch while you are +working on a contribution, please rebase master into your branch and +force push. A pull request should be able to be merged through a +fast-forward, without a merge commit. + +## Testing + +```bash +bundle +vagrant plugin install vagrant-smartos-zones +bundle exec strainer test +``` diff --git a/cookbooks/smf/libraries/helper.rb b/cookbooks/smf/libraries/helper.rb new file mode 100644 index 0000000..ab2b0c6 --- /dev/null +++ b/cookbooks/smf/libraries/helper.rb @@ -0,0 +1,9 @@ +unless defined?(SMFManifest::Helper) + module SMFManifest + # Generic helper that other helpers can inherit from. + # Takes the current node object, as well as an optional + # resource. + class Helper < Struct.new(:node, :resource) + end + end +end diff --git a/cookbooks/smf/libraries/matchers.rb b/cookbooks/smf/libraries/matchers.rb new file mode 100644 index 0000000..e0242e3 --- /dev/null +++ b/cookbooks/smf/libraries/matchers.rb @@ -0,0 +1,9 @@ +if defined?(ChefSpec) + def install_smf(name) + ChefSpec::Matchers::ResourceMatcher.new(:smf, :install, name) + end + + def delete_smf(name) + ChefSpec::Matchers::ResourceMatcher.new(:smf, :delete, name) + end +end diff --git a/cookbooks/smf/libraries/rbac_helper.rb b/cookbooks/smf/libraries/rbac_helper.rb new file mode 100644 index 0000000..6461afe --- /dev/null +++ b/cookbooks/smf/libraries/rbac_helper.rb @@ -0,0 +1,31 @@ +module SMFManifest + # Helper methods for determining whether work needs to be done + # with respect to assigning RBAC values to a service. + class RBACHelper < SMFManifest::Helper + include Chef::Mixin::ShellOut + + def authorization_set? + current_authorization == authorization + end + + def value_authorization_set? + current_value_authorization == value_authorization + end + + def current_authorization + shell_out("svcprop -p general/action_authorization #{resource.name}").stdout.chomp + end + + def current_value_authorization + shell_out("svcprop -p general/value_authorization #{resource.name}").stdout.chomp + end + + def authorization + "solaris.smf.manage.#{resource.authorization_name}" + end + + def value_authorization + "solaris.smf.value.#{resource.authorization_name}" + end + end +end diff --git a/cookbooks/smf/libraries/xml_builder.rb b/cookbooks/smf/libraries/xml_builder.rb new file mode 100644 index 0000000..a9b7f7f --- /dev/null +++ b/cookbooks/smf/libraries/xml_builder.rb @@ -0,0 +1,209 @@ +## This is kind of a hack, to ensure that the cookbook can be +# loaded. On first load, nokogiri may not be present. It is +# installed at load time by recipes/default.rb, so that at run +# time nokogiri will be present. +# +require 'forwardable' + +# rubocop:disable Metrics/ClassLength +module SMFManifest + # XMLBuilder manages the translation of the SMF Chef resource attributes into + # XML that can be parsed by `svccfg import`. + # + # SMFManifest::XMLBuilder.new(resource, node).to_xml + # + class XMLBuilder + # allow delegation + extend Forwardable + + attr_reader :resource, :node + + # delegate methods to :resource + def_delegators :resource, :name, :authorization_name, :dependencies, :duration, :environment, :group, :ignore, + :include_default_dependencies, :locale, :manifest_type, :project, :property_groups, + :service_path, :stability, :working_directory + + public + + def initialize(smf_resource, node) + @resource = smf_resource + @node = node + end + + def to_xml + @xml_output ||= xml_output + end + + protected + + ## methods that need to be called from within the context + # of the Nokogiri builder block need to be protected, rather + # than private. + + def commands + @commands ||= { + 'start' => resource.start_command, + 'stop' => resource.stop_command, + 'restart' => resource.restart_command, + 'refresh' => resource.refresh_command + } + end + + def timeout + @timeouts ||= { + 'start' => resource.start_timeout, + 'stop' => resource.stop_timeout, + 'restart' => resource.restart_timeout, + 'refresh' => resource.refresh_timeout + } + end + + def default_dependencies + if node.platform == 'solaris2' && node.platform_version == '5.11' + [ + { 'name' => 'milestone', 'value' => '/milestone/config' }, + { 'name' => 'fs-local', 'value' => '/system/filesystem/local' }, + { 'name' => 'name-services', 'value' => '/milestone/name-services' }, + { 'name' => 'network', 'value' => '/milestone/network' } + ] + else + [ + { 'name' => 'milestone', 'value' => '/milestone/sysconfig' }, + { 'name' => 'fs-local', 'value' => '/system/filesystem/local' }, + { 'name' => 'name-services', 'value' => '/milestone/name-services' }, + { 'name' => 'network', 'value' => '/milestone/network' } + ] + end + end + + private + + def xml_output + xml_builder = ::Builder::XmlMarkup.new(indent: 2) + xml_builder.instruct! + xml_builder.declare! :DOCTYPE, :service_bundle, :SYSTEM, '/usr/share/lib/xml/dtd/service_bundle.dtd.1' + xml_builder.service_bundle('name' => name, 'type' => 'manifest') do |xml| + xml.service('name' => service_fmri, 'type' => 'service', 'version' => '1') do |service| + service.create_default_instance('enabled' => 'false') + service.single_instance + + if include_default_dependencies + default_dependencies.each do |dependency| + service.dependency('name' => dependency['name'], + 'grouping' => 'require_all', + 'restart_on' => 'none', + 'type' => 'service') do |dep| + dep.service_fmri('value' => "svc:#{dependency['value']}") + end + end + end + + dependencies.each do |dependency| + service.dependency('name' => dependency['name'], + 'grouping' => dependency['grouping'], + 'restart_on' => dependency['restart_on'], + 'type' => dependency['type']) do |dep| + dependency['fmris'].each do |service_fmri| + dep.service_fmri('value' => service_fmri) + end + end + end + + service.method_context(exec_context) do |context| + context.method_credential(credentials) if user != 'root' + + if environment + context.method_environment do |env| + environment.each_pair do |var, value| + env.envvar('name' => var, 'value' => value) + end + end + end + end + + commands.each_pair do |type, command| + if command + service.exec_method('type' => 'method', 'name' => type, 'exec' => command, 'timeout_seconds' => timeout[type]) + end + end + + service.property_group('name' => 'general', 'type' => 'framework') do |group| + group.propval('name' => 'action_authorization', + 'type' => 'astring', + 'value' => "solaris.smf.manage.#{authorization_name}") + group.propval('name' => 'value_authorization', + 'type' => 'astring', + 'value' => "solaris.smf.value.#{authorization_name}") + end + + if sets_duration? || ignores_faults? + service.property_group('name' => 'startd', 'type' => 'framework') do |group| + group.propval('name' => 'duration', 'type' => 'astring', 'value' => duration) if sets_duration? + group.propval('name' => 'ignore_error', 'type' => 'astring', 'value' => ignore.join(',')) if ignores_faults? + end + end + + property_groups.each_pair do |name, properties| + service.property_group('name' => name, 'type' => properties.delete('type') { |_type| 'application' }) do |group| + properties.each_pair do |key, value| + group.propval('name' => key, 'value' => value, 'type' => check_type(value)) + end + end + end + + service.stability('value' => stability) + + service.template do |template| + template.common_name do |common_name| + common_name.loctext(name, 'xml:lang' => locale) + end + end + end + end + + xml_builder.target! + end + + def credentials + creds = { 'user' => user, 'privileges' => resource.privilege_list } + creds.merge!('group' => group) unless group.nil? + creds + end + + def user + resource.user || resource.credentials_user || 'root' + end + + def exec_context + context = {} + context['working_directory'] = working_directory unless working_directory.nil? + context['project'] = project unless project.nil? + context + end + + def check_type(value) + if value == value.to_i + 'integer' + else + 'astring' + end + end + + def ignores_faults? + !ignore.nil? + end + + def sets_duration? + duration != 'contract' + end + + # resource.fmri is set in the SMF :install action of the default provider. + # If there is already a service with a name that is matched by our resource.name + # then we grab the FMRI (fault management resource identifier) from the system. + # If a service is not found, we set this to our own FMRI. + def service_fmri + resource.fmri.nil? || resource.fmri.empty? ? "#{manifest_type}/management/#{name}" : resource.fmri.gsub(/^\//, '') + end + end +end +# rubocop:enable Metrics/ClassLength diff --git a/cookbooks/smf/metadata.json b/cookbooks/smf/metadata.json new file mode 100644 index 0000000..d5aba81 --- /dev/null +++ b/cookbooks/smf/metadata.json @@ -0,0 +1,48 @@ +{ + "name": "smf", + "description": "A light weight resource provider (LWRP) for SMF (Service Management Facility)", + "long_description": "SMF\n===\n\n## Description\n\nService Management Facility (SMF) is a tool in many Illumos and Solaris-derived operating systems\nthat treats services as first class objects of the system. It provides an XML syntax for \ndeclaring how the system can interact with and control a service.\n\nThe SMF cookbook contains providers for creating or modifying a service within the SMF framework.\n\n\n## Requirements\n\nAny operating system that uses SMF, ie Solaris, SmartOS, OpenIndiana etc.\n\nThe `smf` provider depends on the `builder` gem, which can be installed\nvia the `smf::default` recipe.\n\nRequires the RBAC cookbook, which can be found at .\n\nProcesses can be run inside a project wrapper. In this case, look to the Resource Control cookbook,\nwhich can be found at . Note that the SMF LWRP\ndoes not create or manage the project.\n\n\n## Basic Usage\n\nNote that we run the `smf::default` recipe before using LWRPs from this\ncookbook.\n\n```ruby\ninclude_recipe 'smf'\n\nsmf 'my-service' do\n user 'non-root-user'\n start_command 'my-service start'\n start_timeout 10\n stop_command 'pkill my-service'\n stop_timeout 5\n restart_command 'my-service restart'\n restart_timeout 60\n environment 'PATH' => '/home/non-root-user/bin',\n 'RAILS_ENV' => 'staging'\n locale 'C'\n manifest_type 'application'\n service_path '/var/svc/manifest'\n notifies :restart, 'service[my-service]'\nend\n\nservice 'my-service' do\n action :enable\nend\n\nservice 'my-service' do\n action :restart\nend\n```\n\n\n## Attributes\n\nOwnership:\n* `user` - User to run service commands as\n* `group` - Group to run service commands as\n\nRBAC\n* `authorization` - What management and value authorizations should be\n created for this service. Defaults to the service name.\n\nDependency management:\n* `include_default_dependencies` - Service should depend on file system\n and network services. Defaults to `true`. See [Dependencies](#dependencies)\n for more info.\n* `dependency` - an optional array of hashes signifying service and path\n dependencies for this service to run. See [Dependencies](#dependencies).\n\nProcess management:\n* `project` - Name of project to run commands in\n* `start_command`\n* `start_timeout`\n* `stop_command` - defaults to `:kill`, which basically means it will destroy every PID generated from the start command\n* `stop_timeout`\n* `restart_command` - defaults to `stop_command`, then `start_command`\n* `restart_timeout`\n* `refresh_command` - by default SMF treats this as `true`. This will be called when the SMF definition changes or\n when a `notify :reload, 'service[thing]'` is called.\n* `refresh_timeout`\n* `duration` - Can be either `contract`, `wait`, `transient` or\n `child`, but defaults to `contract`. See the [Duration](#duration) section below.\n* `environment` - Hash - Environment variables to set while running commands\n* `ignore` - Array - Faults to ignore in subprocesses. For example, \n if core dumps in children are handled by a master process and you \n don't want SMF thinking the service is exploding, you can ignore \n [\"core\", \"signal\"].\n* `privileges` - Array - An array of privileges to be allowed for started processes.\n Defaults to ['basic', 'net_privaddr']\n* `property_groups` - Hash - This should be in the form `{\"group name\" => {\"type\" => \"application\", \"key\" => \"value\", ...}}`\n* `working_directory` - PWD that SMF should cd to in order to run commands\n* `locale` - Character encoding to use (default \"C\")\n\nManifest/FMRI metadata:\n* `service_path` - defaults to `/var/svc/manifest`\n* `manifest_type` - defaults to `application`\n* `stability` - String - defaults to \"Evolving\". Valid options are\n \"Standard\", \"Stable\", \"Evolving\", \"Unstable\", \"External\" and\n \"Obsolete\"\n\nDeprecated:\n* `credentials_user` - deprecated in favor of `user`\n\n\n## Provider Actions\n\n### :install (default)\n\nThis will drop a manifest XML file into `#{service_path}/#{manifest_type}/#{name}.xml`. If there is already a service\nwith a name that is matched by `new_resource.name` then the FMRI of our manifest will be set to the FMRI of the \npre-existing service. In this case, our properties will be merged into the properties of the pre-existing service.\n\nIn this way, updates to recipes that use the SMF provider will not delete existing service properties, but will add \nor overwrite them.\n\nBecause of this, the SMF provider can be used to update properties for\nservices that are installed via a package manager.\n\n### :delete\n\nRemove an SMF definition. This stops the service if it is running.\n\n### :add_rbac\n\nThis uses the `rbac` cookbook to define permissions that can then be applied to a user. This can be useful when local\nusers should manage services that are added via packages.\n\n```ruby\nsmf \"nginx\" do\n action :add_rbac\nend\n\nrbac_auth \"Allow my user to manage nginx\" do\n user \"my_user\"\n auth \"nginx\"\nend\n```\n\n\n## Resource Notes\n\n### `user`, `working_directory` and `environment`\n\nSMF does a remarkably good job running services as delegated users, and removes a lot of pain if you configure a \nservice correctly. There are many examples online (blogs, etc) of users wrapping their services in shell scripts with \n`start`, `stop`, `restart` arguments. In general it seems as if the intention of these scripts is to take care of the\nproblem of setting environment variables and shelling out as another user.\n\nThe use of init scripts to wrap executables can be unnecessary with SMF, as it provides hooks for all of these use cases. \nWhen using `user`, SMF will assume that the `working_directory` is the user's home directory. This can be\neasily overwritten (to `/home/user/app/current` for a Rails application, for example). One thing to be careful of is \nthat shell profile files will not be loaded. For this reason, if environment variables (such as PATH) are different \non your system or require additional entries arbitrary key/values may be set using the `environment` attribute.\n\nAll things considered, one should think carefully about the need for an init script when working with SMF. For \nwell-behaved applications with simple configuration, an init script is overkill. Applications with endless command-line \noptions or that need a real login shell (for instance ruby applications that use RVM) an init script may make life\neasier.\n\n### Role Based Authorization\n\nBy default the SMF definition creates authorizations based on the\nservice name. The service user is then granted these authorizations. If\nthe service is named `asplosions`, then `solaris.smf.manage.asplosions`\nand `solaris.smf.value.asplosions` will be created.\n\nThe authorization can be changed by manually setting `authorization` on\nthe smf block:\n\n```ruby\nsmf 'asplosions' do\n user 'monkeyking'\n start_command 'asplode'\n authorization 'booms'\nend\n```\n\nThis can be helpful if there are many services configured on a single\nhost, as multiple services can be collapsed into the same\nauthorizations. For instance: https://illumos.org/issues/4968 \n\n### Dependencies\n\nSMF allows services to explicitly list their dependencies on other\nservices. Among other things, this ensures that services are enabled in\nthe proper order on boot, so that a service doesn't fail to start\nbecause another service has not yet been started.\n\nBy default, services created by the SMF LWRP depend on the following other services:\n* svc:/milestone/sysconfig\n* svc:/system/filesystem/local\n* svc:/milestone/name-services\n* svc:/milestone/network\n\nOn Solaris11, `svc:/milestone/sysconfig` is replaced with\n`svc:/milestone/config`.\n\nThese are configured with the attribute `include_default_dependencies`,\nwhich defaults to `true`.\n\nOther dependencies can be specified with the `dependencies` attribute,\nwhich takes an array of hashes as follows:\n\n```ruby\nsmf 'redis'\n\nsmf 'redis-6999' do\n start_command \"...\"\n dependencies [\n {name: 'redis', fmris: ['svc:/application/management/redis'],\n grouping: 'require_all', restart_on: 'restart', type: 'service'}\n ]\nend\n```\n\nValid options for grouping:\n* require_all - All listed FMRIs must be online\n* require_any - Any of the listed FMRIs must be online\n* exclude_all - None of the listed FMRIs can be online\n* optional_all - FMRIs are either online or unable to come online\n\nValid options for restart_on:\n* error - Hardware fault\n* restart - Restarts service if the depedency is restarted\n* refresh - Restarted if the dependency is restarted or refreshed for\n any reason\n* none - Don't do anything\n\nValid options for type:\n* service - expects dependency FMRIs to be other services ie: svc:/type/of/service:instance\n* path - expects FMRIs to be paths, ie file://localhost/etc/redis/redis.conf\n\nNote: the provider currently does not do any validation of these values. Also, type:path has not been extensively\ntested. Use this at your own risk, or improve the provider's compatibility with type:path and submit a pull request!\n\n### Duration\n\nThere are several different ways that SMF can track your service. By default it uses `contract`. \nBasically, this means that it will keep track of the PIDs of all daemonized processes generated from `start_command`.\nIf SMF sees that processes are cycling, it may try to restart the service. If things get too hectic, it\nmay think that your service is flailing and put it into maintenance mode. If this is normal for your service,\nfor instance if you have a master that occasionally reaps processes, you may want to specify additional\nconfiguration options.\n\nIf you have a job that you want managed by SMF, but which is not daemonized, another duration option is\n`transient`. In this mode, SMF will not watch any processes, but will expect that the main process exits cleanly.\nThis can be used, for instance, for a script that must be run at boot time, or for a script that you want to delegate\nto particular users with Role Based Access Control. In this case, the script can be registered with SMF to run as root,\nbut with the start_command delegated to your user.\n\nA third option is `wait`. This covers non-daemonized processes.\n\nA fourth option is `child`.\n\n### Ignore\n\nSometimes you have a case where your service behaves poorly. The Ruby server Unicorn, for example, has a master \nprocess that likes to kill its children. This causes core dumps that SMF will interpret to be a failing service.\nInstead you can `ignore [\"core\", \"signal\"]` and SMF will stop caring about core dumps.\n\n### Privileges\n\nSome system calls require privileges generally only granted to superusers or particular roles. In Solaris, an\nSMF definition can also set specific privileges for contracted processes.\n\nBy default the SMF provider will grant 'basic' and 'net_privaddr' permissions, but this can be set as follows:\n\n```ruby\nsmf 'elasticsearch' do\n start_command 'elasticsearch'\n privileges ['basic', 'proc_lock_memory']\nend\n```\n\nSee the (privileges man page)[https://www.illumos.org/man/5/privileges] for more information.\n\n### Property Groups\n\nProperty Groups are where you can store extra information for SMF to use later. They should be used in the\nfollowing format:\n\n```ruby\nsmf \"my-service\" do\n start_command \"do-something\"\n property_groups({\n \"config\" => {\n \"type\" => \"application\",\n \"my-property\" => \"property value\"\n }\n })\nend\n```\n\n`type` will default to `application`, and is used in the manifest XML to declare how the property group will be\nused. For this reason, `type` can not be used as a property name (ie variable).\n\nOne way to use property groups is to pass variables on to commands, as follows:\n\n```ruby\nrails_env = node[\"from-chef-environment\"][\"rails-env\"]\n\nsmf \"unicorn\" do\n start_command \"bundle exec unicorn_rails -c /home/app_user/app/current/config/%{config/rails_env} -E %{config/rails_env} -D\"\n start_timeout 300\n restart_command \":kill -SIGUSR2\"\n restart_timeout 300\n working_directory \"/home/app_user/app/current\"\n property_groups({\n \"config\" => {\n \"rails_env\" => rails_env\n }\n })\nend\n```\n\nThis is especially handy if you have a case where your commands may come from role attributes, but can\nonly work if they have access to variables set in an environment or computed in a recipe.\n\n### Stability\n\nThis is for reference more than anything, so that administrators of a service know what to expect of possible changes to \nthe service definition.\n\nSee: \n\n\n## Working Examples\n\nPlease see the [examples](https://github.com/livinginthepast/smf/blob/master/EXAMPLES.md) page for\nexample usages.\n\n\n## Cookbook upgrades, possible side effects\n\nChanges to this cookbook may change the way that its internal checksums are generated for a service.\nIf you `notify :restart` any service from within the `smf` block or include a `refresh_command`, please\nbe aware that upgrading this cookbook may trigger a refresh or a registered notification on the first\nsubsequent chef run.\n\n## Contributing\n\n* fork\n* file an issue to track updates/communication\n* add tests\n* rebase master into your branch\n* issue a pull request\n\nPlease do not increment the cookbook version in a fork. Version updates\nwill be done on the master branch after any pull requests are merged.\n\nWhen upstream changes are added to the master branch while you are\nworking on a contribution, please rebase master into your branch and\nforce push. A pull request should be able to be merged through a\nfast-forward, without a merge commit.\n\n## Testing\n\n```bash\nbundle\nvagrant plugin install vagrant-smartos-zones\nbundle exec strainer test\n```\n", + "maintainer": "Eric Saxby", + "maintainer_email": "sax@livinginthepast.org", + "license": "MIT", + "platforms": { + "smartos": ">= 0.0.0" + }, + "dependencies": { + "rbac": ">= 1.0.1" + }, + "recommendations": { + + }, + "suggestions": { + "resource-control": ">= 0.0.0" + }, + "conflicting": { + + }, + "providing": { + + }, + "replacing": { + + }, + "attributes": { + + }, + "groupings": { + + }, + "recipes": { + + }, + "version": "2.2.8", + "source_url": "", + "issues_url": "", + "privacy": false, + "chef_versions": [ + + ], + "ohai_versions": [ + + ] +} diff --git a/cookbooks/smf/metadata.rb b/cookbooks/smf/metadata.rb new file mode 100644 index 0000000..94a4751 --- /dev/null +++ b/cookbooks/smf/metadata.rb @@ -0,0 +1,13 @@ +name 'smf' +maintainer 'Eric Saxby' +maintainer_email 'sax@livinginthepast.org' +license 'MIT' +description 'A light weight resource provider (LWRP) for SMF (Service Management Facility)' +long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) +version '2.2.8' + +supports 'smartos' + +depends 'rbac', '>= 1.0.1' + +suggests 'resource-control' # For managing Solaris projects, when setting project on a manifest diff --git a/cookbooks/smf/providers/default.rb b/cookbooks/smf/providers/default.rb new file mode 100644 index 0000000..76670e1 --- /dev/null +++ b/cookbooks/smf/providers/default.rb @@ -0,0 +1,143 @@ + +require 'chef/mixin/shell_out' +require 'fileutils' +include Chef::Mixin::ShellOut + +def load_current_resource + find_fmri unless new_resource.fmri + + @current_resource = Chef::Resource::Smf.new(new_resource.name) + @current_resource.fmri(new_resource.fmri) + @current_resource.load +end + +action :install do + create_directories + write_manifest + create_rbac_definitions + import_manifest + deduplicate_manifest + add_rbac_permissions + + new_resource.updated_by_last_action(smf_changed?) + new_resource.save_checksum if smf_changed? +end + +action :add_rbac do + create_rbac_definitions + service new_resource.name + + manage = execute "add SMF authorization to allow RBAC for #{new_resource.name}" do + command "svccfg -s #{new_resource.name} " \ + 'setprop general/action_authorization=astring:' \ + "'solaris.smf.manage.#{new_resource.authorization_name}'" + not_if { SMFManifest::RBACHelper.new(node, new_resource).authorization_set? } + notifies :reload, "service[#{new_resource.name}]" + end + + value = execute "add SMF value to allow RBAC for #{new_resource.name}" do + command "svccfg -s #{new_resource.name} " \ + 'setprop general/value_authorization=astring: ' \ + 'solaris.smf.value.#{new_resource.authorization_name}' + not_if { SMFManifest::RBACHelper.new(node, new_resource).value_authorization_set? } + notifies :reload, "service[#{new_resource.name}]" + end + + new_resource.updated_by_last_action(manage.updated_by_last_action? || value.updated_by_last_action?) +end + +action :delete do + new_resource.updated_by_last_action(false) + + if @current_resource.smf_exists? + service new_resource.name do + action [:stop, :disable] + end + + execute "remove service #{new_resource.name} from SMF" do + command "svccfg delete #{new_resource.name}" + end + + delete_manifest + new_resource.remove_checksum + + new_resource.updated_by_last_action(true) + end +end + +private + +def smf_changed? + @current_resource.checksum != new_resource.checksum || !@current_resource.smf_exists? +end + +def find_fmri + fmri_check = shell_out(%(svcs -H -o FMRI #{new_resource.name})) + if fmri_check.exitstatus == 0 + new_resource.fmri fmri_check.stdout.chomp.split(':')[1] + else + new_resource.fmri "/#{new_resource.manifest_type}/management/#{new_resource.name}" + end +end + +def create_directories + Chef::Log.debug "Creating manifest directory at #{new_resource.xml_path}" + FileUtils.mkdir_p new_resource.xml_path +end + +def write_manifest + return unless smf_changed? + + Chef::Log.debug "Writing SMF manifest for #{new_resource.name}" + ::File.open(new_resource.xml_file, 'w') do |file| + file.puts SMFManifest::XMLBuilder.new(new_resource, node).to_xml + end +end + +def delete_manifest + return unless ::File.exist?(new_resource.xml_file) + + Chef::Log.debug "Removing SMF manifest for #{new_resource.name}" + ::File.delete(new_resource.xml_file) +end + +def create_rbac_definitions + rbac new_resource.authorization_name do + action :create + end +end + +def add_rbac_permissions + user = new_resource.user || new_resource.credentials_user || 'root' + + rbac_auth "Add RBAC for #{new_resource.name} to #{user}" do + user user + auth new_resource.authorization_name + not_if { user == 'root' } + end +end + +def import_manifest + return unless smf_changed? + + Chef::Log.debug("importing SMF manifest #{new_resource.xml_file}") + shell_out!("svccfg import #{new_resource.xml_file}") +end + +def deduplicate_manifest + # If we are overwriting properties from an old SMF definition (from pkgsrc, etc) + # there may be redundant XML files that we want to dereference + name = new_resource.name + + duplicate_manifest = shell_out("svcprop #{name} | grep -c manifestfiles").stdout.strip.to_i > 1 + return unless duplicate_manifest + + Chef::Log.debug "Removing duplicate SMF manifest reference from #{name}" + shell_out! "svccfg -s #{name} delprop " \ + "`svcprop #{name} | grep manifestfiles | grep -v #{new_resource.xml_file} | awk '{ print $1 }'` " \ + "&& svcadm refresh #{name}" +end + +def smf_defined?(fmri) + shell_out("svcs #{fmri}").exitstatus == 0 +end diff --git a/cookbooks/smf/recipes/SMFServicesOK.rb b/cookbooks/smf/recipes/SMFServicesOK.rb new file mode 100644 index 0000000..d3f5c1f --- /dev/null +++ b/cookbooks/smf/recipes/SMFServicesOK.rb @@ -0,0 +1,25 @@ +directory '/opt/scripts' do + action :create + mode '0755' + owner 'root' + group 'root' +end + +directory '/opt/local/etc/snmp/conf.d' do + action :create + mode '0755' + owner 'root' + group 'root' +end + +template '/opt/scripts/SMFServicesOK.sh' do + path '/opt/scripts/SMFServicesOK.sh' + source 'SMFServicesOK.sh.erb' + mode '0755' +end + +template 'SMFServicesOK.snmpd.conf' do + path '/opt/local/etc/snmp/conf.d/SMFServicesOK.snmpd.conf' + source 'SMFServicesOK.snmpd.conf.erb' + mode '0644' +end diff --git a/cookbooks/smf/recipes/default.rb b/cookbooks/smf/recipes/default.rb new file mode 100644 index 0000000..72d8f16 --- /dev/null +++ b/cookbooks/smf/recipes/default.rb @@ -0,0 +1,7 @@ +## These libraries need to be installed when the cookbook +# is loaded, otherwise they are not available when the +# cookbook runs. + +chef_gem 'builder' + +require 'builder' diff --git a/cookbooks/smf/resources/default.rb b/cookbooks/smf/resources/default.rb new file mode 100644 index 0000000..6224e19 --- /dev/null +++ b/cookbooks/smf/resources/default.rb @@ -0,0 +1,124 @@ + +require 'chef/mixin/shell_out' +include Chef::Mixin::ShellOut + +actions :install, :add_rbac, :delete +default_action :install + +attribute :name, kind_of: String, name_attribute: true, required: true +attribute :user, kind_of: [String, NilClass], default: nil +attribute :group, kind_of: [String, NilClass], default: nil +attribute :project, kind_of: [String, NilClass], default: nil + +attribute :authorization, kind_of: [String, NilClass], default: nil + +attribute :start_command, kind_of: [String, NilClass], default: nil +attribute :start_timeout, kind_of: Integer, default: 5 +attribute :stop_command, kind_of: String, default: ':kill' +attribute :stop_timeout, kind_of: Integer, default: 5 +attribute :restart_command, kind_of: [String, NilClass], default: nil +attribute :restart_timeout, kind_of: Integer, default: 5 +attribute :refresh_command, kind_of: [String, NilClass], default: nil +attribute :refresh_timeout, kind_of: Integer, default: 5 + +attribute :include_default_dependencies, kind_of: [TrueClass, FalseClass], default: true +attribute :dependencies, kind_of: [Array], default: [] + +attribute :privileges, kind_of: [Array], default: %w(basic net_privaddr) +attribute :working_directory, kind_of: [String, NilClass], default: nil +attribute :environment, kind_of: [Hash, NilClass], default: nil +attribute :locale, kind_of: String, default: 'C' + +attribute :manifest_type, kind_of: String, default: 'application' +attribute :service_path, kind_of: String, default: '/var/svc/manifest' + +attribute :duration, kind_of: String, default: 'contract', regex: '(contract|wait|transient|child)' +attribute :ignore, kind_of: [Array, NilClass], default: nil +attribute :fmri, kind_of: String, default: nil + +attribute :stability, kind_of: String, equal_to: %w(Standard Stable Evolving Unstable External Obsolete), + default: 'Evolving' + +attribute :property_groups, kind_of: Hash, default: {} + +# Deprecated +attribute :credentials_user, kind_of: [String, NilClass], default: nil + +## internal methods + +def xml_path + "#{service_path}/#{manifest_type}" +end + +def xml_file + "#{xml_path}/#{name}.xml" +end + +require 'fileutils' +require 'digest/md5' + +# Save a checksum out to a file, for future chef runs +# +def save_checksum + Chef::Log.debug("Saving checksum for SMF #{name}: #{checksum}") + ::FileUtils.mkdir_p(Chef::Config.checksum_path) + f = ::File.new(checksum_file, 'w') + f.write checksum +end + +def remove_checksum + return unless ::File.exist?(checksum_file) + + Chef::Log.debug("Removing checksum for SMF #{name}") + ::File.delete(checksum_file) +end + +# Load current resource from checksum file and projects database. +# This should only ever be called on @current_resource, never on new_resource. +# +def load + @checksum ||= ::File.exist?(checksum_file) ? ::File.read(checksum_file) : '' + @smf_exists = shell_out("svcs #{fmri}").exitstatus == 0 + Chef::Log.debug("Loaded checksum for SMF #{name}: #{@checksum}") + Chef::Log.debug("SMF service already exists for #{fmri}? #{@smf_exists.inspect}") +end + +def authorization_name + authorization || name +end + +def checksum + attributes = [ + user, credentials_user, group, + project, start_command, start_timeout, stop_command, + stop_timeout, restart_command, restart_timeout, + refresh_command, refresh_timeout, working_directory, + locale, authorization, manifest_type, service_path, + duration, ignore.to_s, include_default_dependencies, + dependencies, fmri, stability, environment_as_string, + privilege_list, property_groups_as_string, '0' + ] + @checksum ||= Digest::MD5.hexdigest(attributes.join(':')) +end + +def checksum_file + "#{Chef::Config.checksum_path}/smf--#{name}" +end + +def environment_as_string + return nil if environment.nil? + environment.inject('') { |memo, k, v| memo << [k, v].join('|') } +end + +def privilege_list + privileges.join(',') +end + +def property_groups_as_string + return nil if property_groups.empty? + property_groups.inject('') { |memo, k, v| memo << [k, v].join('|') } +end + +def smf_exists? + !!@smf_exists +end diff --git a/cookbooks/smf/templates/default/SMFServicesOK.sh.erb b/cookbooks/smf/templates/default/SMFServicesOK.sh.erb new file mode 100644 index 0000000..b135216 --- /dev/null +++ b/cookbooks/smf/templates/default/SMFServicesOK.sh.erb @@ -0,0 +1,13 @@ +#!/bin/bash +# if we're on SunOS 5.10+, we should check for beat services. + +if [ "`uname -s`" = "SunOS" ] && [ `uname -r|cut -d. -f1` -ge 5 ] && [ `uname -r|cut -d. -f2` -ge 10 ] +then + B=`svcs -Ha |egrep -v "disabled|online|legacy_run"` + if [ "foo$B" == "foo" ] + then + echo "OK" + else + echo $B + fi +fi diff --git a/cookbooks/smf/templates/default/SMFServicesOK.snmpd.conf.erb b/cookbooks/smf/templates/default/SMFServicesOK.snmpd.conf.erb new file mode 100644 index 0000000..8d3add8 --- /dev/null +++ b/cookbooks/smf/templates/default/SMFServicesOK.snmpd.conf.erb @@ -0,0 +1 @@ +extend SMFServicesOK /opt/scripts/SMFServicesOK.sh diff --git a/cookbooks/tar/CHANGELOG.md b/cookbooks/tar/CHANGELOG.md index bc3636c..7a0fc5f 100644 --- a/cookbooks/tar/CHANGELOG.md +++ b/cookbooks/tar/CHANGELOG.md @@ -2,6 +2,17 @@ This file is used to list changes made in each version of the tar cookbook. +## 2.1.1 (2017-06-13) + +- Fix metadata source and issues links. + +## 2.1.0 (2017-05-30) + +- Test with Local Delivery instead of Rake +- Update apache2 license string +- Attribute -> Property in the custom resource +- Remove class_eval and require Chef 12.7+ + ## 2.0.0 (2017-02-16) - Converted the existing LWRPs to custom resources and bumped the minimum supported Chef release to 12.5 diff --git a/cookbooks/tar/metadata.json b/cookbooks/tar/metadata.json index 0e5ddc0..21c367e 100644 --- a/cookbooks/tar/metadata.json +++ b/cookbooks/tar/metadata.json @@ -1 +1 @@ -{"name":"tar","version":"2.0.0","description":"Installs tar and two resources to manage remote tar packages","long_description":"# tar Cookbook\n\n[![Build Status](https://travis-ci.org/chef-cookbooks/tar.svg?branch=master)](https://travis-ci.org/chef-cookbooks/tar) [![Cookbook Version](https://img.shields.io/cookbook/v/tar.svg)](https://supermarket.chef.io/cookbooks/tar)\n\nInstalls tar and includes resources for managing remote tar files. `tar_package` handles remote source package compilation. `tar_extract` handles retrieving remote tar files and extracting them locally.\n\n## Resources\n\n### tar_package\n\nA `tar_package` LWRP provides an easy way to download remote files and compile and install them. This only works for the most basic Autoconf programs that can do `./configure && make && make install`.\n\n#### Actions\n\n- :install: Installs the package\n\n#### Properties\n\n- source: name attribute. The source remote URL.\n- prefix: Directory to be used as the `--prefix` configure flag.\n- source_directory: Directory to which source files are download.\n- creates: A file this command creates - if the file exists, the command will not be run.\n- configure_flags: Array of additional flags to be passed to `./configure`.\n- archive_name: Specify a different name for the downloaded archive. Use it if the directory name inside the tar file is different than the name defined in the URL. Additionally, `tar_package` supports most `remote_file` [attributes](https://docs.chef.io/chef/resources.html#remote-file).\n\n#### Example\n\n```\ntar_package 'http://pgfoundry.org/frs/download.php/1446/pgpool-3.4.1.tar.gz' do\n prefix '/usr/local'\n creates '/usr/local/bin/pgpool'\nend\n```\n\nThis will download, compile, and install the package from the given URL and install it into /usr/local.\n\n### tar_extract\n\nA `tar_extract` LWRP provides an easy way to download remote tar files and extract them to a local directory.\n\n#### Actions\n\n- :extract: Extracts the tar file from a url\n- :extract_local: Extracts the tar file from a local file path\n\n#### Properties\n\n- source: name attribute. The source remote URL.\n- target_dir: Directory to extract into, e.g. tar xzf -C (target_dir)\n- download_dir: Directory to which tarball is downloaded (defaults to chef cache which requires root `group` and `user`).\n- creates: A file this command creates - if the file exists, the command will not be run.\n- compress_char: Flag for compression type, such as `z` for `gzip`. `man tar` for options.\n- tar_flags: Array of additional flags to be passed to tar xzf command.\n- group: Group name or group ID to extract the archive under. If set to non-root group, point to a `download_dir` the group has permission to access.\n- user: User name or user ID to extract the archive under. If set to non-root user, point to a `download_dir` the user has permission to access. Additionally, `tar_extract` supports most `remote_file` [attributes](https://docs.chef.io/chef/resources.html#remote-file).\n\n#### Example\n\n```\ntar_extract 'http://dev.mycoderepo.com/artifacts/mycode-1.2.3.tar.gz' do\n target_dir '/opt/myapp/mycode'\n creates '/opt/myapp/mycode/lib'\n tar_flags [ '-P', '--strip-components 1' ]\nend\n```\n\nThis will download the tarball to cache, extract the contents to /opt/myapp/mycode, use the file '/opt/myapp/mycode/lib' to determine idempotency, and pass both '-P' and '--strip-components 1' flags to the tar xzf command.\n\n```\ntar_extract '/tmp/mycode-1.2.3.tar.gz' do\n action :extract_local\n target_dir '/opt/myapp/mycode'\n creates '/opt/myapp/mycode/lib'\nend\n```\n\nThis will extract the contents of /tmp/mycode-1.2.3.tar.gz to /opt/myapp/mycode and use the file '/opt/myapp/mycode/lib' to determine idempotency.\n\n## ChefSpec Matchers\n\nChefSpec matchers are defined for tar_package and tar_extract.\n\n## LICENSE AND AUTHOR\n\nAuthor:: Nathan L Smith ([nathan@cramerdev.com](mailto:nathan@cramerdev.com)) Author:: George Miranda ([gmiranda@chef.io](mailto:gmiranda@chef.io)) Author:: Mark Van de Vyver ([mark@@taqtiqa.com](mailto:mark@@taqtiqa.com))\n\nCopyright 2011, Cramer Development, Inc. Copyright 2011, Opscode, Inc. Copyright 2013, TAQTIQA LLC.\n\nLicensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except in compliance with the License. You may obtain a copy of the License at\n\n```\nhttp://www.apache.org/licenses/LICENSE-2.0\n```\n\nUnless required by applicable law or agreed to in writing, software distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.\n","maintainer":"Chef Software, Inc.","maintainer_email":"cookbooks@chef.io","license":"Apache 2.0","platforms":{"ubuntu":">= 0.0.0","debian":">= 0.0.0","redhat":">= 0.0.0","centos":">= 0.0.0","suse":">= 0.0.0","opensuse":">= 0.0.0","opensuseleap":">= 0.0.0","scientific":">= 0.0.0","oracle":">= 0.0.0","amazon":">= 0.0.0","zlinux":">= 0.0.0"},"dependencies":{},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{}} \ No newline at end of file +{"name":"tar","version":"2.1.1","description":"Installs tar and two resources to manage remote tar packages","long_description":"# tar Cookbook\n\n[![Build Status](https://travis-ci.org/chef-cookbooks/tar.svg?branch=master)](https://travis-ci.org/chef-cookbooks/tar) [![Cookbook Version](https://img.shields.io/cookbook/v/tar.svg)](https://supermarket.chef.io/cookbooks/tar)\n\nInstalls tar and includes resources for managing remote tar files. `tar_package` handles remote source package compilation. `tar_extract` handles retrieving remote tar files and extracting them locally.\n\n## Resources\n\n### tar_package\n\nA `tar_package` LWRP provides an easy way to download remote files and compile and install them. This only works for the most basic Autoconf programs that can do `./configure && make && make install`.\n\n#### Actions\n\n- :install: Installs the package\n\n#### Properties\n\n- source: name attribute. The source remote URL.\n- prefix: Directory to be used as the `--prefix` configure flag.\n- source_directory: Directory to which source files are download.\n- creates: A file this command creates - if the file exists, the command will not be run.\n- configure_flags: Array of additional flags to be passed to `./configure`.\n- archive_name: Specify a different name for the downloaded archive. Use it if the directory name inside the tar file is different than the name defined in the URL. Additionally, `tar_package` supports most `remote_file` [attributes](https://docs.chef.io/chef/resources.html#remote-file).\n\n#### Example\n\n```\ntar_package 'http://pgfoundry.org/frs/download.php/1446/pgpool-3.4.1.tar.gz' do\n prefix '/usr/local'\n creates '/usr/local/bin/pgpool'\nend\n```\n\nThis will download, compile, and install the package from the given URL and install it into /usr/local.\n\n### tar_extract\n\nA `tar_extract` LWRP provides an easy way to download remote tar files and extract them to a local directory.\n\n#### Actions\n\n- :extract: Extracts the tar file from a url\n- :extract_local: Extracts the tar file from a local file path\n\n#### Properties\n\n- source: name attribute. The source remote URL.\n- target_dir: Directory to extract into, e.g. tar xzf -C (target_dir)\n- download_dir: Directory to which tarball is downloaded (defaults to chef cache which requires root `group` and `user`).\n- creates: A file this command creates - if the file exists, the command will not be run.\n- compress_char: Flag for compression type, such as `z` for `gzip`. `man tar` for options.\n- tar_flags: Array of additional flags to be passed to tar xzf command.\n- group: Group name or group ID to extract the archive under. If set to non-root group, point to a `download_dir` the group has permission to access.\n- user: User name or user ID to extract the archive under. If set to non-root user, point to a `download_dir` the user has permission to access. Additionally, `tar_extract` supports most `remote_file` [attributes](https://docs.chef.io/chef/resources.html#remote-file).\n\n#### Example\n\n```\ntar_extract 'http://dev.mycoderepo.com/artifacts/mycode-1.2.3.tar.gz' do\n target_dir '/opt/myapp/mycode'\n creates '/opt/myapp/mycode/lib'\n tar_flags [ '-P', '--strip-components 1' ]\nend\n```\n\nThis will download the tarball to cache, extract the contents to /opt/myapp/mycode, use the file '/opt/myapp/mycode/lib' to determine idempotency, and pass both '-P' and '--strip-components 1' flags to the tar xzf command.\n\n```\ntar_extract '/tmp/mycode-1.2.3.tar.gz' do\n action :extract_local\n target_dir '/opt/myapp/mycode'\n creates '/opt/myapp/mycode/lib'\nend\n```\n\nThis will extract the contents of /tmp/mycode-1.2.3.tar.gz to /opt/myapp/mycode and use the file '/opt/myapp/mycode/lib' to determine idempotency.\n\n## ChefSpec Matchers\n\nChefSpec matchers are defined for tar_package and tar_extract.\n\n## LICENSE AND AUTHOR\n\nAuthor:: Nathan L Smith ([nathan@cramerdev.com](mailto:nathan@cramerdev.com)) Author:: George Miranda ([gmiranda@chef.io](mailto:gmiranda@chef.io)) Author:: Mark Van de Vyver ([mark@@taqtiqa.com](mailto:mark@@taqtiqa.com))\n\nCopyright 2011, Cramer Development, Inc. Copyright 2011, Opscode, Inc. Copyright 2013, TAQTIQA LLC.\n\nLicensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except in compliance with the License. You may obtain a copy of the License at\n\n```\nhttp://www.apache.org/licenses/LICENSE-2.0\n```\n\nUnless required by applicable law or agreed to in writing, software distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.\n","maintainer":"Chef Software, Inc.","maintainer_email":"cookbooks@chef.io","license":"Apache-2.0","platforms":{"ubuntu":">= 0.0.0","debian":">= 0.0.0","redhat":">= 0.0.0","centos":">= 0.0.0","suse":">= 0.0.0","opensuse":">= 0.0.0","opensuseleap":">= 0.0.0","scientific":">= 0.0.0","oracle":">= 0.0.0","amazon":">= 0.0.0","zlinux":">= 0.0.0"},"dependencies":{},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{},"source_url":"https://github.com/chef-cookbooks/tar","issues_url":"https://github.com/chef-cookbooks/tar/issues","chef_version":[[">= 12.7"]],"ohai_version":[]} \ No newline at end of file diff --git a/cookbooks/tar/recipes/default.rb b/cookbooks/tar/recipes/default.rb index 2295cd8..c80eec2 100644 --- a/cookbooks/tar/recipes/default.rb +++ b/cookbooks/tar/recipes/default.rb @@ -1,5 +1,5 @@ # -# Cookbook Name:: tar +# Cookbook:: tar # Recipe:: default # # Author:: Nathan L Smith () diff --git a/cookbooks/tar/resources/extract.rb b/cookbooks/tar/resources/extract.rb index c4f12e3..aa45263 100644 --- a/cookbooks/tar/resources/extract.rb +++ b/cookbooks/tar/resources/extract.rb @@ -1,5 +1,5 @@ # -# Cookbook Name:: tar +# Cookbook:: tar # Resource:: extract # # Author:: Nathan L Smith () @@ -34,11 +34,11 @@ property :compress_char, String, default: 'z' property :tar_flags, [String, Array], default: [] property :user, String, default: 'root' property :headers, Hash -property :use_etag, [TrueClass, FalseClass], default: true -property :use_last_modified, [TrueClass, FalseClass], default: true -property :atomic_update, [TrueClass, FalseClass], default: true -property :force_unlink, [TrueClass, FalseClass], default: false -property :manage_symlink_source, [TrueClass, FalseClass] +property :use_etag, [true, false], default: true +property :use_last_modified, [true, false], default: true +property :atomic_update, [true, false], default: true +property :force_unlink, [true, false], default: false +property :manage_symlink_source, [true, false] require 'shellwords' @@ -78,7 +78,7 @@ action :extract_local do extract_tar(new_resource.name, new_resource) end -action_class.class_eval do +action_class do def extract_tar(local_archive, r) execute "extract #{local_archive}" do flags = if r.tar_flags.is_a?(String) diff --git a/cookbooks/tar/resources/package.rb b/cookbooks/tar/resources/package.rb index dd75489..104d0dc 100644 --- a/cookbooks/tar/resources/package.rb +++ b/cookbooks/tar/resources/package.rb @@ -1,5 +1,5 @@ # -# Cookbook Name:: tar +# Cookbook:: tar # Resource:: package # # Author:: Nathan L Smith () @@ -19,19 +19,19 @@ # limitations under the License. # -attribute :source, String, name_attribute: true -attribute :headers, Hash, default: {} -attribute :prefix, String -attribute :source_directory, String, default: '/usr/local/src' -attribute :creates, String -attribute :configure_flags, Array, default: [] -attribute :archive_name, String -attribute :headers, Hash -attribute :use_etag, [TrueClass, FalseClass], default: true -attribute :use_last_modified, [TrueClass, FalseClass], default: true -attribute :atomic_update, [TrueClass, FalseClass], default: true -attribute :force_unlink, [TrueClass, FalseClass], default: false -attribute :manage_symlink_source, [TrueClass, FalseClass] +property :source, String, name_property: true +property :headers, Hash, default: {} +property :prefix, String +property :source_directory, String, default: '/usr/local/src' +property :creates, String +property :configure_flags, Array, default: [] +property :archive_name, String +property :headers, Hash +property :use_etag, [true, false], default: true +property :use_last_modified, [true, false], default: true +property :atomic_update, [true, false], default: true +property :force_unlink, [true, false], default: false +property :manage_symlink_source, [true, false] action :install do r = new_resource diff --git a/cookbooks/mysql2_chef_gem/.foodcritic b/cookbooks/windows/.foodcritic similarity index 50% rename from cookbooks/mysql2_chef_gem/.foodcritic rename to cookbooks/windows/.foodcritic index b9f8767..6c8fa23 100644 --- a/cookbooks/mysql2_chef_gem/.foodcritic +++ b/cookbooks/windows/.foodcritic @@ -1 +1,2 @@ +~FC059 ~FC016 diff --git a/cookbooks/windows/CHANGELOG.md b/cookbooks/windows/CHANGELOG.md index 1fa57ef..c1df254 100644 --- a/cookbooks/windows/CHANGELOG.md +++ b/cookbooks/windows/CHANGELOG.md @@ -1,362 +1,535 @@ -windows Cookbook CHANGELOG -======================= -This file is used to list changes made in each version of the windows cookbook. - -v1.38.4 --------------------- -- [PR 295](https://github.com/chef-cookbooks/windows/pull/295) - Escape `http_acl` username -- [PR 293](https://github.com/chef-cookbooks/windows/pull/293) - Separating assignments to `code_script` and `guard_script` as they should be different scripts and not hold the same reference -- [Issue 298](https://github.com/chef-cookbooks/windows/issues/298) - `windows_certificate_binding` is ignoring `store_name` attribute and always saving to `MY` -- [Issue 296](https://github.com/chef-cookbooks/windows/pull/302) - Fixes `windows_certificate` idempotentcy on chef 11 clients - -v1.38.3 --------------------- -- Make `windows_task` resource idempotent (double quotes need to be single when comparing) -- [Issue 245](https://github.com/chef-cookbooks/windows/issues/256) - Fix `No resource, method, or local variable named `password' for `Chef::Provider::WindowsTask'` when `interactive_enabled` is `true` - -v1.38.2 --------------------- -- Lazy-load windows-pr gem library files. Chef 12.5 no longer includes the windows-pr gem. Earlier versions of this cookbook will not compile on Chef 12.5. - -v1.38.1 (2015-07-28) --------------------- -- Publishing without extended metadata - -v1.38.0 (2015-07-27) --------------------- -- Do not set new_resource.password to nil, Fixes #219, Fixes #220 -- Add `windows_certificate` resource #212 -- Add `windows_http_acl` resource #214 - -v1.37.0 (2015-05-14) --------------------- -- fix `windows_package` `Chef.set_resource_priority_array` warning -- update `windows_task` to support tasks in folders -- fix `windows_task` delete action -- replace `windows_task` name attribute with 'task_name' -- add :end action to 'windows_task' -- Tasks created with the `windows_task` resource default to the SYSTEM account -- The force attribute for `windows_task` makes the :create action update the definition. -- `windows_task` :create action will force an update of the task if the user or command differs from the currently configured setting. -- add default provider for `windows_feature` -- add a helper to make sure `WindowsRebootHandler` works in ChefSpec -- added a source and issues url to the metadata for Supermarket -- updated the Gemfile and .kitchen.yml to reflect the latest test-kitchen windows guest support -- started tests using the kitchen-pester verifier - -v1.36.6 (2014-12-18) --------------------- -- reverting all chef_gem compile_time work - -v1.36.5 (2014-12-18) --------------------- -- Fix zipfile provider - -v1.36.4 (2014-12-18) --------------------- -- Fix Chef chef_gem with Chef::Resource::ChefGem.method_defined?(:compile_time) - -v1.36.3 (2014-12-18) --------------------- -- Fix Chef chef_gem below 12.1.0 - -v1.36.2 (2014-12-17) --------------------- -- Being explicit about usage of the chef_gem's compile_time property. -- Eliminating future deprecation warnings in Chef 12.1.0 - -v1.36.1 (2014-12-17) --------------------- -- [PR 160](https://github.com/chef-cookbooks/windows/pull/160) - Fix Chef 11.10 / versions without windows_package in core - -v1.36.0 (2014-12-16) --------------------- -- [PR 145](https://github.com/chef-cookbooks/windows/pull/145) - do not fail on non-existant task -- [PR 144](https://github.com/chef-cookbooks/windows/pull/144) - Add a zip example to the README -- [PR 110](https://github.com/chef-cookbooks/windows/pull/110) - More zip documentation -- [PR 148](https://github.com/chef-cookbooks/windows/pull/148) - Add an LWRP for font installation -- [PR 151](https://github.com/chef-cookbooks/windows/pull/151) - Fix windows_package on Chef 12, add integration tests -- [PR 129](https://github.com/chef-cookbooks/windows/pull/129) - Add enable/disable actions to task LWRP -- [PR 115](https://github.com/chef-cookbooks/windows/pull/115) - require Chef::Mixin::PowershellOut before using it -- [PR 88](https://github.com/chef-cookbooks/windows/pull/88) - Code 1003 from servermanagercmd.exe is valid - -v1.34.8 (2014-10-31) --------------------- -- [Issue 137](https://github.com/chef-cookbooks/windows/issues/137) - windows_path resource breaks with ruby 2.x - -v1.34.6 (2014-09-22) --------------------- -- [Chef-2009](https://github.com/chef/chef/issues/2009) - Patch to work around a regression in [Chef](https://github.com/chef/chef) - -v1.34.2 (2014-08-12) --------------------- -- [Issue 99](https://github.com/chef-cookbooks/windows/issues/99) - Remove rubygems / Internet wmi-lite dependency (PR #108) - -v1.34.0 (2014-08-04) --------------------- -- [Issue 99](https://github.com/chef-cookbooks/windows/issues/99) - Use wmi-lite to fix Chef 11.14.2 break in rdp-ruby-wmi dependency - -v1.32.1 (2014-07-15) --------------------- -- Fixes broken cookbook release - -v1.32.0 (2014-07-11) --------------------- -- Add ChefSpec resource methods to allow notification testing (@sneal) -- Add use_inline_resources to providers (@micgo) -- [COOK-4728] - Allow reboot handler to be used as an exception handler -- [COOK-4620] - Ensure win_friendly_path doesn't error out when ALT_SEPARATOR is nil - -v1.31.0 (2014-05-07) --------------------- -- [COOK-2934] - Add windows_feature support for 2 new DISM attributes: all, source - -v1.30.2 (2014-04-02) --------------------- -- [COOK-4414] - Adding ChefSpec matchers - -v1.30.0 (2014-02-14) --------------------- -- [COOK-3715] - Unable to create a startup task with no login -- [COOK-4188] - Add powershell_version method to return Powershell version - -v1.12.8 (2014-01-21) --------------------- -- [COOK-3988] Don't unescape URI before constructing it. - -v1.12.6 (2014-01-03) --------------------- -- [COOK-4168] Circular dep on powershell - moving powershell libraries into windows. removing dependency on powershell - -v1.12.4 -------- -Fixing depend/depends typo in metadata.rb - - -v1.12.2 -------- -### Bug -- **[COOK-4110](https://tickets.chef.io/browse/COOK-4110)** - feature_servermanager installed? method regex bug - - -v1.12.0 -------- -### Bug -- **[COOK-3793](https://tickets.chef.io/browse/COOK-3793)** - parens inside parens of README.md don't render - -### New Feature -- **[COOK-3714](https://tickets.chef.io/browse/COOK-3714)** - Powershell features provider and delete support. - - -v1.11.0 -------- -### Improvement -- **[COOK-3724](https://tickets.chef.io/browse/COOK-3724)** - Rrecommend built-in resources over cookbook resources -- **[COOK-3515](https://tickets.chef.io/browse/COOK-3515)** - Remove unprofessional comment from library -- **[COOK-3455](https://tickets.chef.io/browse/COOK-3455)** - Add Windows Server 2012R2 to windows cookbook version helper - -### Bug -- **[COOK-3542](https://tickets.chef.io/browse/COOK-3542)** - Fix an issue where `windows_zipfile` fails with LoadError -- **[COOK-3447](https://tickets.chef.io/browse/COOK-3447)** - Allow Overriding Of The Default Reboot Timeout In windows_reboot_handler -- **[COOK-3382](https://tickets.chef.io/browse/COOK-3382)** - Allow windows_task to create `on_logon` tasks -- **[COOK-2098](https://tickets.chef.io/browse/COOK-2098)** - Fix and issue where the `windows_reboot` handler is ignoring the reboot time - -### New Feature -- **[COOK-3458](https://tickets.chef.io/browse/COOK-3458)** - Add support for `start_date` and `start_time` in `windows_task` - - -v1.10.0 -------- -### Improvement - -- [COOK-3126]: `windows_task` should support the on start frequency -- [COOK-3127]: Support the force option on task create and delete - -v1.9.0 ------- -### Bug - -- [COOK-2899]: windows_feature fails when a feature install requires a - reboot -- [COOK-2914]: Foodcritic failures in Cookbooks -- [COOK-2983]: windows cookbook has foodcritic failures - -### Improvement - -- [COOK-2686]: Add Windows Server 2012 to version.rb so other - depending chef scripts can detect Windows Server 2012 - -v1.8.10 -------- -When using Windows qualified filepaths (C:/foo), the #absolute? method -for URI returns true, because "C" is the scheme. - -This change checks that the URI is http or https scheme, so it can be -passed off to remote_file appropriately. - -* [COOK-2729] - allow only http, https URI schemes - -v1.8.8 ------- -* [COOK-2729] - helper should use URI rather than regex and bare string - -v1.8.6 ------- -* [COOK-968] - `windows_package` provider should gracefully handle paths with spaces -* [COOK-222] - `windows_task` resource does not declare :change action -* [COOK-241] - Windows cookbook should check for redefined constants -* [COOK-248] - Windows package install type is case sensitive - -v1.8.4 ------- -* [COOK-2336] - MSI That requires reboot returns with RC 3010 and - causes chef run failure -* [COOK-2368] - `version` attribute of the `windows_package` provider - should be documented - -v1.8.2 ------- -**Important**: Use powershell in nodes expanded run lists to ensure - powershell is downloaded, as powershell has a dependency on this - cookbook; v1.8.0 created a circular dependency. - -* [COOK-2301] - windows 1.8.0 has circular dependency on powershell - -v1.8.0 ------- -* [COOK-2126] - Add checksum attribute to `windows_zipfile` -* [COOK-2142] - Add printer and `printer_port` LWRPs -* [COOK-2149] - Chef::Log.debug Windows Package command line -* [COOK-2155] -`windows_package` does not send checksum to - `cached_file` in `installer_type` - -v1.7.0 ------- -* [COOK-1745] - allow for newer versions of rubyzip - -v1.6.0 ------- -* [COOK-2048] - undefined method for Falseclass on task :change when - action is :nothing (and task doesn't exist) -* [COOK-2049] - Add `windows_pagefile` resource - -v1.5.0 ------- -* [COOK-1251] - Fix LWRP "NotImplementedError" -* [COOK-1921] - Task LWRP will return true for resource exists when no - other scheduled tasks exist -* [COOK-1932] - Include :change functionality to windows task lwrp - -v1.4.0: ------- -* [COOK-1571] - `windows_package` resource (with msi provider) does not -accept spaces in filename -* [COOK-1581] - Windows cookbook needs a scheduled tasks LWRP -* [COOK-1584] - `windows_registry` should support all registry types - -v1.3.4 ------- -* [COOK-1173] - `windows_registry` throws Win32::Registry::Error for - action :remove on a nonexistent key -* [COOK-1182] - windows package sets start window title instead of - quoting a path -* [COOK-1476] - zipfile lwrp should support :zip action -* [COOK-1485] - package resource fails to perform install correctly - when "source" contains quote -* [COOK-1519] - add action :remove for path lwrp - -v1.3.2 ------- -* [COOK-1033] - remove the `libraries/ruby_19_patches.rb` file which - causes havoc on non-Windows systems. -* [COOK-811] - add a timeout parameter attribute for `windows_package` - -v1.3.0 ------- -* [COOK-1323] - Update for changes in Chef 0.10.10. - - Setting file mode doesn't make sense on Windows (package provider - - and `reboot_handler` recipe) - - Prefix ::Win32 to avoid namespace collision with Chef::Win32 - - (`registry_helper` library) - - Use chef_gem instead of gem_package so gems get installed correctly - under the Ruby environment Chef runs in (reboot_handler recipe, - zipfile provider) - -v1.2.12 -------- -* [COOK-1037] - specify version for rubyzip gem -* [COOK-1007] - `windows_feature` does not work to remove features with - dism -* [COOK-667] - shortcut resource + provider for Windows platforms - -v1.2.10 -------- -* [COOK-939] - add `type` parameter to `windows_registry` to allow binary registry keys. -* [COOK-940] - refactor logic so multiple values get created. - -v1.2.8 ------- -* FIX: Older Windows (Windows Server 2003) sometimes return 127 on successful forked commands -* FIX: `windows_package`, ensure we pass the WOW* registry redirection flags into reg.open - -v1.2.6 ------- -* patch to fix [CHEF-2684], Open4 is named Open3 in Ruby 1.9 -* Ruby 1.9's Open3 returns 0 and 42 for successful commands -* retry keyword can only be used in a rescue block in Ruby 1.9 - -v1.2.4 ------- -* `windows_package` - catch Win32::Registry::Error that pops up when searching certain keys - -v1.2.2 ------- -* combined numerous helper libarires for easier sharing across libaries/LWRPs -* renamed Chef::Provider::WindowsFeature::Base file to the more descriptive `feature_base.rb` -* refactored `windows_path` LWRP - * :add action should MODIFY the the underlying ENV variable (vs CREATE) - * deleted greedy :remove action until it could be made more idempotent -* added a `windows_batch` resource/provider for running batch scripts remotely - -v1.2.0 ------- -* [COOK-745] gracefully handle required server restarts on Windows platform - * WindowsRebootHandler for requested and pending reboots - * `windows_reboot` LWRP for requesting (receiving notifies) reboots - * `reboot_handler` recipe for enabling WindowsRebootHandler as a report handler -* [COOK-714] Correct initialize misspelling -* RegistryHelper - new `get_values` method which returns all values for a particular key. - -v1.0.8 ------- -* [COOK-719] resource/provider for managing windows features -* [COOK-717] remove `windows_env_vars` resource as env resource exists in core chef -* new `Windows::Version` helper class -* refactored `Windows::Helper` mixin - -v1.0.6 ------- -* added `force_modify` action to `windows_registry` resource -* add `win_friendly_path` helper -* re-purpose default recipe to install useful supporting windows related gems - -v1.0.4 ------- -* [COOK-700] new resources and improvements to the `windows_registry` provider (thanks Paul Morton!) - * Open the registry in the bitednes of the OS - * Provide convenience methods to check if keys and values exit - * Provide convenience method for reading registry values - * NEW - `windows_auto_run` resource/provider - * NEW - `windows_env_vars` resource/provider - * NEW - `windows_path` resource/provider -* re-write of the `windows_package` logic for determining current installed packages -* new checksum attribute for `windows_package` resource...useful for remote packages - -v1.0.2 ------- -* [COOK-647] account for Wow6432Node registry redirecter -* [COOK-656] begin/rescue on win32/registry - -v1.0.0 ------- -* [COOK-612] initial release +# windows Cookbook CHANGELOG + +This file is used to list changes made in each version of the windows cookbook. + +## 3.1.1 (2017-06-13) + +- Replace Windows 7 testing with Windows 10 testing +- Expand debug logging in the pagefile resource +- Require path in the share resource instead of raising if it's missing +- Make pagefile properly fail the run if the command fails to run + +## 3.1.0 (2017-05-30) + +- Updated resource documentation for windows_pagefile +- Declare windows_feature as why-runnable +- Remove action_class.class_eval usage and require 12.7+ as class_eval is causing issues with later versions of Chef + +## 3.0.5 (2017-04-07) + +- Add support for windows_task resource to run on non-English editions of Windows +- Ensure chef-client 12.6 compatibility with action_class.class_eval + +## 3.0.4 (2017-03-29) + +- restoring the `cached_file` helper as downstream cookbooks use it. + +## 3.0.3 (2017-03-28) + +- Correct a typo in a Log message + +## 3.0.2 (2017-03-21) + +- Fix `windows_zipfile` resource to properly download and cache the zip archives + +## 3.0.1 (2017-03-17) + +- Fix `windows_share` to be fully idempotent. Fixes #447 + +## 3.0.0 (2017-03-15) + +**Warning** This release includes multiple breaking changes as we refactored all existing resources and resolved many longstanding bugs. We highly recommend exercising caution and fully testing this new version before rolling it out to a production environment. + +### Breaking changes + +- This cookbook now requires Chef 12.6 or later and we highly recommend even more recent Chef 12 releases as they resolve critical Windows bugs and include new Windows specific functionality. +- The windows_package resource has been removed as it is built into chef-client 12.6+ and the built in version is faster / more robust. +- The powershell out helper has been removed as it is now included in chef-client 12.6+ +- The default recipe no longer installs the various Windows rubygems required for non-omnibus chef-client installs. This was a leftover from Chef 10 and is no longer necessary, or desired, as we ship these gems in every Windows chef release. +- windows_feature has been heavily refactored and in doing so the method used to control the underlying providers has changed. You can no longer specify which windows_feature provider to use by setting `node['windows']['feature_provider']` or by setting the `provider` property on the resource itself. Instead you must set `install_method` to specify the correct underlying installation method. You can also now reference the resources directly by using `windows_feature_servermanagercmd`, `windows_feature_powershell` or `windows_feature_dism` instead of `windows_feature` + +- Windows_font's `file` property has been renamed to `name` to avoid collisions with the Chef file resource. + +### Other Changes + +- All LWRPs in this cookbook have been refactored to be custom resources +- windows_path, windows_shortcut, and windows_zipfile have been updated to be idempotent with support for why-run mode and proper notification when the resources actually update +- windows_pagefile now validates the name of the pagefile to avoid cryptic error messages +- A new `share` resource has been added for setting up Windows shares +- TrustedPeople certificate store has been added to the list of allowed store_names in the certificate resources +- version helper constant definitions has been improved +- A new `all` property has been added to the Windows feature resource to install all dependent features. See the windows feature test recipe for usage examples. +- Windows feature now accepts an array of features, which greatly speeds up feature installs and simplifies recipe code +- The path resource now accepts paths with either forward slashes or backslashes and correctly adds the path using Windows style backslash. +- The powershell provider for windows_feature resource has been fixed to properly import ServerManager in the :remove action +- Testing has been switched from a Rakefile to the new Delivery local mode +- Several issues with testing the resources on non-Windows hosts in ChefSpec have been resolved +- A new `source` property has been added to the windows_feature_powershell resource +- Additional test suites have been added to Test Kitchen to cover all resources and those test suites are now being executed in AppVeyer on every PR +- Travis CI testing has been removed and all testing is being performed in AppVeyer + +## 2.1.1 (2016-11-23) + +- Make sure the ohai plugin is available when installing features + +## 2.1.0 (2016-11-22) + +- Reduce expensive executions of dism in windows_feature by using a new Ohai plugin +- Add guard around chef_version metadata for Opsworks and older Chef 12 clients +- Update the rakefile to the latest +- Add deprecation dates for the windows_package and powershell functionality that has been moved to core Chef. These will be removed 4/17 when we release Chef 13 +- Provide helper method to get windows version info +- Allow defining http acl using SDDL + +## 2.0.2 (2016-09-07) + +- Added the powershell_out mixin back to allow for Chef 12.1-12.3 compatibility +- Set the dependency back to Chef 12.1 + +## 2.0.1 (2016-09-07) + +- Clarify the platforms we support in the readme +- Require Chef 12.4 which included powershell_out + +## 2.0.0 (2016-09-07) + +This cookbook now requires Chef 12.1+. Resources (lwrps) that have been moved into the chef-client have been removed from this cookbook. While the functionality in the chef-client is similar, and in many cases improved, the names and properties have changed in some cases. Make sure to check for full documentation on each of these resources, and as usual carefully test your cookbooks before upgrading to this new release. + +### Removed resources and helpers: + +- windows_reboot provider +- windows_batch provider +- windows_registry provider +- Powershell out for only_if / not_if statements +- Windows Architecture Helper +- Reboot handler and the dependency on the chef_handler cookbook + +#### Changes resource behavior + +- For Chef clients 12.6 and later the windows_package provider will no longer be used as windows_package logic is now included in Chef. Chef 12.1 - 12.5.1 clients will continue to default to the windows_package provider in this cookbook for full compatibility. + +#### Additional changes + +- Updated and expanded testing +- Fixed the windows_feature powershell provider to run on Windows 2008 / 2008 R2 +- Added TrustedPublisher as a valid cert store_name +- Updated the certificate_binding resource to respect the app_id property +- Added why-run support to the auto_run resource + +## 1.44.3 (2016-08-16) + +- Remove support for ChefSpec <4.1 in the matchers +- Add missing Chefspec matchers + +## 1.44.2 (2016-08-15) + +- Add missing windows_font matcher +- Add chef_version to the metadata +- Switch from Rubocop to Cookstyle and use our improved Rakefile +- Remove test deps from the Gemfile that are in ChefDK + +## v1.44.1 + +- [PR 375](https://github.com/chef-cookbooks/windows/pull/375) - Fix comparison of string to number in platform_version +- [PR 376](https://github.com/chef-cookbooks/windows/pull/376) - Switch to cookstyle, update gem deps and other minor stuff +- [PR 377](https://github.com/chef-cookbooks/windows/pull/377) - add test and check for feature installation through powershell + +## v1.44.0 + +- [PR 372](https://github.com/chef-cookbooks/windows/pull/372) - Support Server 2008 for feature installs via PowerShell + +## v1.43.0 + +- [PR 369](https://github.com/chef-cookbooks/windows/pull/369) - Add a enable_windows_task matcher + +## v1.42.0 + +- [PR 365](https://github.com/chef-cookbooks/windows/pull/365) - Escape command quotes when passing to schtasks + +## v1.41.0 + +- [PR 364](https://github.com/chef-cookbooks/windows/pull/364) - Configurable font source + +## v1.40.0 + +- [PR 357](https://github.com/chef-cookbooks/windows/pull/357) - Fixes for schtasks +- [PR 359](https://github.com/chef-cookbooks/windows/pull/359) - take bundler out of the appveyor build +- [PR 356](https://github.com/chef-cookbooks/windows/pull/356) - Misc fixes and updates +- [PR 355](https://github.com/chef-cookbooks/windows/pull/355) - bump and pin rubocop, fix broken cop +- [PR 348](https://github.com/chef-cookbooks/windows/pull/348) - Make notify work for `windows_task` + +## v1.39.2 + +- [PR 329](https://github.com/chef-cookbooks/windows/pull/329) - Silence `compile_time` warning for `chef_gem` +- [PR 338](https://github.com/chef-cookbooks/windows/pull/338) - ChefSpec matchers for `windows_certificate` +- [PR 341](https://github.com/chef-cookbooks/windows/pull/341) - Updated rubocop and FoodCritic compliance +- [PR 336](https://github.com/chef-cookbooks/windows/pull/336) - Fixed where clause compliance with PS v1/v2 + +## v1.39.1 + +- [PR 325](https://github.com/chef-cookbooks/windows/pull/325) - Raise an error if a bogus feature is given to the powershell `windows_feature` provider +- [PR 326](https://github.com/chef-cookbooks/windows/pull/326) - Fix `windows_font` and copy the font file before installation + +## v1.39.0 + +- [PR 305](https://github.com/chef-cookbooks/windows/pull/305) - Added `months` attribute to `windows_task` and allow `frequency_modifier` to accept values 'FIRST', 'SECOND', 'THIRD', 'FOURTH', 'LAST', and 'LASTDAY' for monthly frequency +- [PR 310](https://github.com/chef-cookbooks/windows/pull/310) - Fix `windows_task` breaks when there is a space in the user name +- [PR 314](https://github.com/chef-cookbooks/windows/pull/314) - fixes reboot handling on some chef versions below 11.12 +- [PR 317](https://github.com/chef-cookbooks/windows/pull/317) - Adds a `disable_windows_task` matcher +- [PR 311](https://github.com/chef-cookbooks/windows/pull/311) - Implements the `cwd` attribute of `windows_task` +- [PR 318](https://github.com/chef-cookbooks/windows/pull/318) - Use dsl instead of manual resource instanciation +- [PR 303](https://github.com/chef-cookbooks/windows/pull/303) - Fix `http_acl` idempotency when user name contains a space +- [PR 257](https://github.com/chef-cookbooks/windows/pull/257) - Speed up windows_feature dism provider +- [PR 319](https://github.com/chef-cookbooks/windows/pull/319) - Add a `.kitchen.cloud.yml` for kitchen testing on Azure +- [PR 315](https://github.com/chef-cookbooks/windows/pull/315) - Deprecate `windows_package` and forward to `Chef::Provider::Package::Windows` when running 12.6 or higher + +## v1.38.4 + +- [PR 295](https://github.com/chef-cookbooks/windows/pull/295) - Escape `http_acl` username +- [PR 293](https://github.com/chef-cookbooks/windows/pull/293) - Separating assignments to `code_script` and `guard_script` as they should be different scripts and not hold the same reference +- [Issue 298](https://github.com/chef-cookbooks/windows/issues/298) - `windows_certificate_binding` is ignoring `store_name` attribute and always saving to `MY` +- [Issue 296](https://github.com/chef-cookbooks/windows/pull/302) - Fixes `windows_certificate` idempotentcy on chef 11 clients + +## v1.38.3 + +- Make `windows_task` resource idempotent (double quotes need to be single when comparing) +- [Issue 245](https://github.com/chef-cookbooks/windows/issues/256) - Fix `No resource, method, or local variable named`password' for `Chef::Provider::WindowsTask'` when `interactive_enabled` is `true` + +## v1.38.2 + +- Lazy-load windows-pr gem library files. Chef 12.5 no longer includes the windows-pr gem. Earlier versions of this cookbook will not compile on Chef 12.5. + +## v1.38.1 (2015-07-28) + +- Publishing without extended metadata + +## v1.38.0 (2015-07-27) + +- Do not set new_resource.password to nil, Fixes #219, Fixes #220 +- Add `windows_certificate` resource #212 +- Add `windows_http_acl` resource #214 + +## v1.37.0 (2015-05-14) + +- fix `windows_package` `Chef.set_resource_priority_array` warning +- update `windows_task` to support tasks in folders +- fix `windows_task` delete action +- replace `windows_task` name attribute with 'task_name' +- add :end action to 'windows_task' +- Tasks created with the `windows_task` resource default to the SYSTEM account +- The force attribute for `windows_task` makes the :create action update the definition. +- `windows_task` :create action will force an update of the task if the user or command differs from the currently configured setting. +- add default provider for `windows_feature` +- add a helper to make sure `WindowsRebootHandler` works in ChefSpec +- added a source and issues url to the metadata for Supermarket +- updated the Gemfile and .kitchen.yml to reflect the latest test-kitchen windows guest support +- started tests using the kitchen-pester verifier + +## v1.36.6 (2014-12-18) + +- reverting all chef_gem compile_time work + +## v1.36.5 (2014-12-18) + +- Fix zipfile provider + +## v1.36.4 (2014-12-18) + +- Fix Chef chef_gem with Chef::Resource::ChefGem.method_defined?(:compile_time) + +## v1.36.3 (2014-12-18) + +- Fix Chef chef_gem below 12.1.0 + +## v1.36.2 (2014-12-17) + +- Being explicit about usage of the chef_gem's compile_time property. +- Eliminating future deprecation warnings in Chef 12.1.0 + +## v1.36.1 (2014-12-17) + +- [PR 160](https://github.com/chef-cookbooks/windows/pull/160) - Fix Chef 11.10 / versions without windows_package in core + +## v1.36.0 (2014-12-16) + +- [PR 145](https://github.com/chef-cookbooks/windows/pull/145) - do not fail on non-existant task +- [PR 144](https://github.com/chef-cookbooks/windows/pull/144) - Add a zip example to the README +- [PR 110](https://github.com/chef-cookbooks/windows/pull/110) - More zip documentation +- [PR 148](https://github.com/chef-cookbooks/windows/pull/148) - Add an LWRP for font installation +- [PR 151](https://github.com/chef-cookbooks/windows/pull/151) - Fix windows_package on Chef 12, add integration tests +- [PR 129](https://github.com/chef-cookbooks/windows/pull/129) - Add enable/disable actions to task LWRP +- [PR 115](https://github.com/chef-cookbooks/windows/pull/115) - require Chef::Mixin::PowershellOut before using it +- [PR 88](https://github.com/chef-cookbooks/windows/pull/88) - Code 1003 from servermanagercmd.exe is valid + +## v1.34.8 (2014-10-31) + +- [Issue 137](https://github.com/chef-cookbooks/windows/issues/137) - windows_path resource breaks with ruby 2.x + +## v1.34.6 (2014-09-22) + +- [Chef-2009](https://github.com/chef/chef/issues/2009) - Patch to work around a regression in [Chef](https://github.com/chef/chef) + +## v1.34.2 (2014-08-12) + +- [Issue 99](https://github.com/chef-cookbooks/windows/issues/99) - Remove rubygems / Internet wmi-lite dependency (PR #108) + +## v1.34.0 (2014-08-04) + +- [Issue 99](https://github.com/chef-cookbooks/windows/issues/99) - Use wmi-lite to fix Chef 11.14.2 break in rdp-ruby-wmi dependency + +## v1.32.1 (2014-07-15) + +- Fixes broken cookbook release + +## v1.32.0 (2014-07-11) + +- Add ChefSpec resource methods to allow notification testing (@sneal) +- Add use_inline_resources to providers (@micgo) +- [COOK-4728] - Allow reboot handler to be used as an exception handler +- [COOK-4620] - Ensure win_friendly_path doesn't error out when ALT_SEPARATOR is nil + +## v1.31.0 (2014-05-07) + +- [COOK-2934] - Add windows_feature support for 2 new DISM attributes: all, source + +## v1.30.2 (2014-04-02) + +- [COOK-4414] - Adding ChefSpec matchers + +## v1.30.0 (2014-02-14) + +- [COOK-3715] - Unable to create a startup task with no login +- [COOK-4188] - Add powershell_version method to return Powershell version + +## v1.12.8 (2014-01-21) + +- [COOK-3988] Don't unescape URI before constructing it. + +## v1.12.6 (2014-01-03) + +- [COOK-4168] Circular dep on powershell - moving powershell libraries into windows. removing dependency on powershell + +## v1.12.4 + +Fixing depend/depends typo in metadata.rb + +## v1.12.2 + +### Bug + +- **[COOK-4110](https://tickets.chef.io/browse/COOK-4110)** - feature_servermanager installed? method regex bug + +## v1.12.0 + +### Bug + +- **[COOK-3793](https://tickets.chef.io/browse/COOK-3793)** - parens inside parens of README.md don't render + +### New Feature + +- **[COOK-3714](https://tickets.chef.io/browse/COOK-3714)** - Powershell features provider and delete support. + +## v1.11.0 + +### Improvement + +- **[COOK-3724](https://tickets.chef.io/browse/COOK-3724)** - Rrecommend built-in resources over cookbook resources +- **[COOK-3515](https://tickets.chef.io/browse/COOK-3515)** - Remove unprofessional comment from library +- **[COOK-3455](https://tickets.chef.io/browse/COOK-3455)** - Add Windows Server 2012R2 to windows cookbook version helper + +### Bug + +- **[COOK-3542](https://tickets.chef.io/browse/COOK-3542)** - Fix an issue where `windows_zipfile` fails with LoadError +- **[COOK-3447](https://tickets.chef.io/browse/COOK-3447)** - Allow Overriding Of The Default Reboot Timeout In windows_reboot_handler +- **[COOK-3382](https://tickets.chef.io/browse/COOK-3382)** - Allow windows_task to create `on_logon` tasks +- **[COOK-2098](https://tickets.chef.io/browse/COOK-2098)** - Fix and issue where the `windows_reboot` handler is ignoring the reboot time + +### New Feature + +- **[COOK-3458](https://tickets.chef.io/browse/COOK-3458)** - Add support for `start_date` and `start_time` in `windows_task` + +## v1.10.0 + +### Improvement + +- [COOK-3126]: `windows_task` should support the on start frequency +- [COOK-3127]: Support the force option on task create and delete + +## v1.9.0 + +### Bug + +- [COOK-2899]: windows_feature fails when a feature install requires a reboot +- [COOK-2914]: Foodcritic failures in Cookbooks +- [COOK-2983]: windows cookbook has foodcritic failures + +### Improvement + +- [COOK-2686]: Add Windows Server 2012 to version.rb so other depending chef scripts can detect Windows Server 2012 + +## v1.8.10 + +When using Windows qualified filepaths (C:/foo), the #absolute? method for URI returns true, because "C" is the scheme. + +This change checks that the URI is http or https scheme, so it can be passed off to remote_file appropriately. + +- [COOK-2729] - allow only http, https URI schemes + +## v1.8.8 + +- [COOK-2729] - helper should use URI rather than regex and bare string + +## v1.8.6 + +- [COOK-968] - `windows_package` provider should gracefully handle paths with spaces +- [COOK-222] - `windows_task` resource does not declare :change action +- [COOK-241] - Windows cookbook should check for redefined constants +- [COOK-248] - Windows package install type is case sensitive + +## v1.8.4 + +- [COOK-2336] - MSI That requires reboot returns with RC 3010 and causes chef run failure +- [COOK-2368] - `version` attribute of the `windows_package` provider should be documented + +## v1.8.2 + +**Important**: Use powershell in nodes expanded run lists to ensure powershell is downloaded, as powershell has a dependency on this cookbook; v1.8.0 created a circular dependency. + +- [COOK-2301] - windows 1.8.0 has circular dependency on powershell + +## v1.8.0 + +- [COOK-2126] - Add checksum attribute to `windows_zipfile` +- [COOK-2142] - Add printer and `printer_port` LWRPs +- [COOK-2149] - Chef::Log.debug Windows Package command line +- [COOK-2155] -`windows_package` does not send checksum to `cached_file` in `installer_type` + +## v1.7.0 + +- [COOK-1745] - allow for newer versions of rubyzip + +## v1.6.0 + +- [COOK-2048] - undefined method for Falseclass on task :change when action is :nothing (and task doesn't exist) +- [COOK-2049] - Add `windows_pagefile` resource + +## v1.5.0 + +- [COOK-1251] - Fix LWRP "NotImplementedError" +- [COOK-1921] - Task LWRP will return true for resource exists when no other scheduled tasks exist +- [COOK-1932] - Include :change functionality to windows task lwrp + +## v1.4.0: + +- [COOK-1571] - `windows_package` resource (with msi provider) does not accept spaces in filename +- [COOK-1581] - Windows cookbook needs a scheduled tasks LWRP +- [COOK-1584] - `windows_registry` should support all registry types + +## v1.3.4 + +- [COOK-1173] - `windows_registry` throws Win32::Registry::Error for action :remove on a nonexistent key +- [COOK-1182] - windows package sets start window title instead of quoting a path +- [COOK-1476] - zipfile lwrp should support :zip action +- [COOK-1485] - package resource fails to perform install correctly when "source" contains quote +- [COOK-1519] - add action :remove for path lwrp + +## v1.3.2 + +- [COOK-1033] - remove the `libraries/ruby_19_patches.rb` file which causes havoc on non-Windows systems. +- [COOK-811] - add a timeout parameter attribute for `windows_package` + +## v1.3.0 + +- [COOK-1323] - Update for changes in Chef 0.10.10. + + - Setting file mode doesn't make sense on Windows (package provider + - and `reboot_handler` recipe) + - Prefix ::Win32 to avoid namespace collision with Chef::Win32 + - (`registry_helper` library) + - Use chef_gem instead of gem_package so gems get installed correctly under the Ruby environment Chef runs in (reboot_handler recipe, zipfile provider) + +## v1.2.12 + +- [COOK-1037] - specify version for rubyzip gem +- [COOK-1007] - `windows_feature` does not work to remove features with dism +- [COOK-667] - shortcut resource + provider for Windows platforms + +## v1.2.10 + +- [COOK-939] - add `type` parameter to `windows_registry` to allow binary registry keys. +- [COOK-940] - refactor logic so multiple values get created. + +## v1.2.8 + +- FIX: Older Windows (Windows Server 2003) sometimes return 127 on successful forked commands +- FIX: `windows_package`, ensure we pass the WOW* registry redirection flags into reg.open + +## v1.2.6 + +- patch to fix [CHEF-2684], Open4 is named Open3 in Ruby 1.9 +- Ruby 1.9's Open3 returns 0 and 42 for successful commands +- retry keyword can only be used in a rescue block in Ruby 1.9 + +## v1.2.4 + +- `windows_package` - catch Win32::Registry::Error that pops up when searching certain keys + +## v1.2.2 + +- combined numerous helper libarires for easier sharing across libaries/LWRPs +- renamed Chef::Provider::WindowsFeature::Base file to the more descriptive `feature_base.rb` +- refactored `windows_path` LWRP + + - :add action should MODIFY the the underlying ENV variable (vs CREATE) + - deleted greedy :remove action until it could be made more idempotent + +- added a `windows_batch` resource/provider for running batch scripts remotely + +## v1.2.0 + +- [COOK-745] gracefully handle required server restarts on Windows platform + + - WindowsRebootHandler for requested and pending reboots + - `windows_reboot` LWRP for requesting (receiving notifies) reboots + - `reboot_handler` recipe for enabling WindowsRebootHandler as a report handler + +- [COOK-714] Correct initialize misspelling + +- RegistryHelper - new `get_values` method which returns all values for a particular key. + +## v1.0.8 + +- [COOK-719] resource/provider for managing windows features +- [COOK-717] remove `windows_env_vars` resource as env resource exists in core chef +- new `Windows::Version` helper class +- refactored `Windows::Helper` mixin + +## v1.0.6 + +- added `force_modify` action to `windows_registry` resource +- add `win_friendly_path` helper +- re-purpose default recipe to install useful supporting windows related gems + +## v1.0.4 + +- [COOK-700] new resources and improvements to the `windows_registry` provider (thanks Paul Morton!) + + - Open the registry in the bitednes of the OS + - Provide convenience methods to check if keys and values exit + - Provide convenience method for reading registry values + - NEW - `windows_auto_run` resource/provider + - NEW - `windows_env_vars` resource/provider + - NEW - `windows_path` resource/provider + +- re-write of the `windows_package` logic for determining current installed packages + +- new checksum attribute for `windows_package` resource...useful for remote packages + +## v1.0.2 + +- [COOK-647] account for Wow6432Node registry redirecter +- [COOK-656] begin/rescue on win32/registry + +## v1.0.0 + +- [COOK-612] initial release diff --git a/cookbooks/chef_handler/CONTRIBUTING.md b/cookbooks/windows/CONTRIBUTING.md similarity index 100% rename from cookbooks/chef_handler/CONTRIBUTING.md rename to cookbooks/windows/CONTRIBUTING.md diff --git a/cookbooks/windows/MAINTAINERS.md b/cookbooks/windows/MAINTAINERS.md new file mode 100644 index 0000000..9f6bd2e --- /dev/null +++ b/cookbooks/windows/MAINTAINERS.md @@ -0,0 +1,21 @@ + + +# Maintainers + +This file lists how this cookbook project is maintained. When making changes to the system, this file tells you who needs to review your patch - you need a review from an existing maintainer for the cookbook to provide a :+1: on your pull request. Additionally, you need to not receive a veto from a Lieutenant or the Project Lead. + +Check out [How Cookbooks are Maintained](https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/CONTRIBUTING.MD) for details on the process and how to become a maintainer or the project lead. + +# Project Maintainer +* [Adam Edwards](https://github.com/adamedx) + +# Maintainers +* [Adam Edwards](https://github.com/adamedx) +* [Kartik Null Cating-Subramanian](https://github.com/ksubrama) +* [Steven Murawski](https://github.com/smurawski) +* [Matt Wrock](https://github.com/mwrock) +* [Jay Mundrawala](https://github.com/jaym) +* [Claire McQuin](https://github.com/mcquin) +* [Salim Alam](https://github.com/chefsalim) +* [Tim Smith](https://github.com/tas50) +* [Jennifer Davis](https://github.com/sigje) diff --git a/cookbooks/windows/README.md b/cookbooks/windows/README.md index 64cb14e..90e9e9c 100644 --- a/cookbooks/windows/README.md +++ b/cookbooks/windows/README.md @@ -1,890 +1,803 @@ -Windows Cookbook -================ -[![Build Status](https://travis-ci.org/chef-cookbooks/windows.svg?branch=master)](http://travis-ci.org/chef-cookbooks/windows) -[![Cookbook Version](https://img.shields.io/cookbook/v/windows.svg)](https://supermarket.chef.io/cookbooks/windows) - -Provides a set of Windows-specific primitives (Chef resources) meant to aid in the creation of cookbooks/recipes targeting the Windows platform. - - -Requirements ------------- -#### Platforms -* Windows Vista -* Windows 7 -* Windows Server 2008 (R1, R2) -* Windows 8, 8.1 -* Windows Server 2012 (R1, R2) - -#### Chef -- Chef 11+ - -#### Cookbooks -* chef_handler (`windows::reboot_handler` leverages the chef_handler LWRP) - - -Attributes ----------- -* `node['windows']['allow_pending_reboots']` - used to configure the `WindowsRebootHandler` (via the `windows::reboot_handler` recipe) to act on pending reboots. default is true (ie act on pending reboots). The value of this attribute only has an effect if the `windows::reboot_handler` is in a node's run list. -* `node['windows']['allow_reboot_on_failure']` - used to register the `WindowsRebootHandler` (via the `windows::reboot_handler` recipe) as an exception handler too to act on reboots not only at the end of successful Chef runs, but even at the end of failed runs. default is false (ie reboot only after successful runs). The value of this attribute only has an effect if the `windows::reboot_handler` is in a node's run list. - - -Resource/Provider ------------------ -### windows_auto_run -#### Actions -- `:create` - Create an item to be run at login -- `:remove` - Remove an item that was previously setup to run at login - -#### Attribute Parameters -- `name` - Name attribute. The name of the value to be stored in the registry -- `program` - The program to be run at login -- `args` - The arguments for the program - -#### Examples -Run BGInfo at login - -```ruby -windows_auto_run 'BGINFO' do - program 'C:/Sysinternals/bginfo.exe' - args '\'C:/Sysinternals/Config.bgi\' /NOLICPROMPT /TIMER:0' - not_if { Registry.value_exists?(AUTO_RUN_KEY, 'BGINFO') } - action :create -end -``` - -### windows_batch -This resource is now deprecated and will be removed in a future version of this cookbook. Chef >= 11.6.0 includes a built-in [batch](http://docs.chef.io/resource_batch.html) resource. - -Execute a batch script using the cmd.exe interpreter (much like the script resources for bash, csh, powershell, perl, python and ruby). A temporary file is created and executed like other script resources, rather than run inline. By their nature, Script resources are not idempotent, as they are completely up to the user's imagination. Use the `not_if` or `only_if` meta parameters to guard the resource for idempotence. - -#### Actions -- `:run` - run the batch file - -#### Attribute Parameters -- `command` - name attribute. Name of the command to execute. -- `code` - quoted string of code to execute. -- `creates` - a file this command creates - if the file exists, the command will not be run. -- `cwd` - current working directory to run the command from. -- `flags` - command line flags to pass to the interpreter when invoking. -- `user` - A user name or user ID that we should change to before running this command. -- `group` - A group name or group ID that we should change to before running this command. - -#### Examples -```ruby -windows_batch 'unzip_and_move_ruby' do - code <<-EOH - 7z.exe x #{Chef::Config[:file_cache_path]}/ruby-1.8.7-p352-i386-mingw32.7z -oC:\\source -r -y - xcopy C:\\source\\ruby-1.8.7-p352-i386-mingw32 C:\\ruby /e /y - EOH -end -``` - -```ruby -windows_batch 'echo some env vars' do - code <<-EOH - echo %TEMP% - echo %SYSTEMDRIVE% - echo %PATH% - echo %WINDIR% - EOH -end -``` - -### windows_certificate - -Installs a certificate into the Windows certificate store from a file, and grants read-only access to the private key for designated accounts. -Due to current limitations in winrm, installing certificated remotely may not work if the operation requires a user profile. Operations on the local machine store should still work. - -#### Actions -- `:create` - creates or updates a certificate. -- `:delete` - deletes a certificate. -- `:acl_add` - adds read-only entries to a certificate's private key ACL. - -#### Attribute Parameters -- `source` - name attribute. The source file (for create and acl_add), thumprint (for delete and acl_add) or subject (for delete). -- `pfx_password` - the password to access the source if it is a pfx file. -- `private_key_acl` - array of 'domain\account' entries to be granted read-only access to the certificate's private key. This is not idempotent. -- `store_name` - the certificate store to maniplate. One of MY (default : personal store), CA (trusted intermediate store) or ROOT (trusted root store). -- `user_store` - if false (default) then use the local machine store; if true then use the current user's store. - -#### Examples -```ruby -# Add PFX cert to local machine personal store and grant accounts read-only access to private key -windows_certificate "c:/test/mycert.pfx" do - pfx_password "password" - private_key_acl ["acme\fred", "pc\jane"] -end -``` - -```ruby -# Add cert to trusted intermediate store -windows_certificate "c:/test/mycert.cer" do - store_name "CA" -end -``` - -```ruby -# Remove all certicates matching the subject -windows_certificate "me.acme.com" do - action :delete -end -``` - -### windows_certificate_binding - -Binds a certificate to an HTTP port in order to enable TLS communication. - -#### Actions -- `:create` - creates or updates a binding. -- `:delete` - deletes a binding. - -#### Attribute Parameters -- `cert_name` - name attribute. The thumprint(hash) or subject that identifies the certicate to be bound. -- `name_kind` - indicates the type of cert_name. One of :subject (default) or :hash. -- `address` - the address to bind against. Default is 0.0.0.0 (all IP addresses). -- `port` - the port to bind against. Default is 443. -- `app_id` - the GUID that defines the application that owns the binding. Default is the values used by IIS. -- `store_name` - the store to locate the certificate in. One of MY (default : personal store), CA (trusted intermediate store) or ROOT (trusted root store). - -#### Examples -```ruby -# Bind the first certificate matching the subject to the default TLS port -windows_certificate_binding "me.acme.com" do -end -``` - -```ruby -# Bind a cert from the CA store with the given hash to port 4334 -windows_certificate_binding "me.acme.com" do - cert_name "d234567890a23f567c901e345bc8901d34567890" - name_kind :hash - store_name "CA" - port 4334 -end -``` - -### windows_feature -Windows Roles and Features can be thought of as built-in operating system packages that ship with the OS. A server role is a set of software programs that, when they are installed and properly configured, lets a computer perform a specific function for multiple users or other computers within a network. A Role can have multiple Role Services that provide functionality to the Role. Role services are software programs that provide the functionality of a role. Features are software programs that, although they are not directly parts of roles, can support or augment the functionality of one or more roles, or improve the functionality of the server, regardless of which roles are installed. Collectively we refer to all of these attributes as 'features'. - -This resource allows you to manage these 'features' in an unattended, idempotent way. - -There are two providers for the `windows_features` which map into Microsoft's two major tools for managing roles/features: [Deployment Image Servicing and Management (DISM)](http://msdn.microsoft.com/en-us/library/dd371719%28v=vs.85%29.aspx) and [Servermanagercmd](http://technet.microsoft.com/en-us/library/ee344834%28WS.10%29.aspx) (The CLI for Server Manager). As Servermanagercmd is deprecated, Chef will set the default provider to `Chef::Provider::WindowsFeature::DISM` if DISM is present on the system being configured. The default provider will fall back to `Chef::Provider::WindowsFeature::ServerManagerCmd`. - -For more information on Roles, Role Services and Features see the [Microsoft TechNet article on the topic](http://technet.microsoft.com/en-us/library/cc754923.aspx). For a complete list of all features that are available on a node type either of the following commands at a command prompt: - -```text -dism /online /Get-Features -servermanagercmd -query -``` - -#### Actions -- `:install` - install a Windows role/feature -- `:remove` - remove a Windows role/feature - -#### Attribute Parameters -- `feature_name` - name of the feature/role to install. The same feature may have different names depending on the provider used (ie DHCPServer vs DHCP; DNS-Server-Full-Role vs DNS). -- `all` - Boolean. Optional. Default: false. DISM provider only. Forces all dependencies to be installed. -- `source` - String. Optional. DISM provider only. Uses local repository for feature install. - -#### Providers -- **Chef::Provider::WindowsFeature::DISM**: Uses Deployment Image Servicing and Management (DISM) to manage roles/features. -- **Chef::Provider::WindowsFeature::ServerManagerCmd**: Uses Server Manager to manage roles/features. -- **Chef::Provider::WindowsFeaturePowershell**: Uses Powershell to manage roles/features. (see [COOK-3714](https://tickets.chef.io/browse/COOK-3714) - -#### Examples -Enable the node as a DHCP Server - -```ruby -windows_feature 'DHCPServer' do - action :install -end -``` - -Enable TFTP - -```ruby -windows_feature 'TFTP' do - action :install -end -``` - -Enable .Net 3.5.1 on Server 2012 using repository files on DVD and -install all dependencies - -```ruby -windows_feature "NetFx3" do - action :install - all true - source "d:\sources\sxs" -end -``` - -Disable Telnet client/server - -```ruby -%w[TelnetServer TelnetClient].each do |feature| - windows_feature feature do - action :remove - end -end -``` - -Add SMTP Feature with powershell provider - -```ruby -windows_feature "smtp-server" do - action :install - all true - provider :windows_feature_powershell -end -``` - -### windows_font -Installs a font. - -Font files should be included in the cookbooks - -#### Actions -- `:install` - install a font to the system fonts directory. - -#### Attribute Parameters -- `file` - The name of the font file name to install. It should exist in the files/default directory of the cookbook you're calling windows_font from. Defaults to the resource name. - -#### Examples - -```ruby -windows_font 'Code New Roman.otf' -``` - -### windows_http_acl -Sets the Access Control List for an http URL to grant non-admin accounts permission to open HTTP endpoints. - -#### Actions -- `:create` - creates or updates the ACL for a URL. -- `:delete` - deletes the ACL from a URL. - -#### Attribute Parameters -- `url` - the name of the url to be created/deleted. -- `user` - the name (domain\user) of the user or group to be granted permission to the URL. Mandatory for create. Only one user or group can be granted permission so this replaces any previously defined entry. - -#### Examples - -```ruby -windows_http_acl 'http://+:50051/' do - user 'pc\\fred' -end -``` - -```ruby -windows_http_acl 'http://+:50051/' do - action :delete -end -``` - -### windows_package -Manage Windows application packages in an unattended, idempotent way. - -The following application installers are currently supported: - -* MSI packages -* InstallShield -* Wise InstallMaster -* Inno Setup -* Nullsoft Scriptable Install System - -If the proper installer type is not passed into the resource's installer_type attribute, the provider will do it's best to identify the type by introspecting the installation package. If the installation type cannot be properly identified the `:custom` value can be passed into the installer_type attribute along with the proper flags for silent/quiet installation (using the `options` attribute..see example below). - -__PLEASE NOTE__ - For proper idempotence the resource's `package_name` should be the same as the 'DisplayName' registry value in the uninstallation data that is created during package installation. The easiest way to definitively find the proper 'DisplayName' value is to install the package on a machine and search for the uninstall information under the following registry keys: - -* `HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall` -* `HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Uninstall` -* `HKEY_LOCAL_MACHINE\Software\Wow6464Node\Microsoft\Windows\CurrentVersion\Uninstall` - -For maximum flexibility the `source` attribute supports both remote and local installation packages. - -#### Actions -- `:install` - install a package -- `:remove` - remove a package. The remove action is completely hit or miss as many application uninstallers do not support a full silent/quiet mode. - -#### Attribute Parameters -- `package_name` - name attribute. The 'DisplayName' of the application installation package. -- `source` - The source of the windows installer. This can either be a URI or a local path. -- `installer_type` - They type of windows installation package. Valid values include :msi, :inno, :nsis, :wise, :installshield, :custom. If this value is not provided, the provider will do it's best to identify the installer type through introspection of the file. -- `checksum` - useful if source is remote, the SHA-256 checksum of the file--if the local file matches the checksum, Chef will not download it -- `options` - Additional options to pass the underlying installation command -- `timeout` - set a timeout for the package download (default 600 seconds) -- `version` - The version number of this package, as indicated by the 'DisplayVersion' value in one of the 'Uninstall' registry keys. If the given version number does equal the 'DisplayVersion' in the registry, the package will be installed. -- `success_codes` - set an array of possible successful installation - return codes. Previously this was hardcoded, but certain MSIs may - have a different return code, e.g. 3010 for reboot required. Must be - an array, and defaults to `[0, 42, 127]`. - -#### Examples - -Install PuTTY (InnoSetup installer) -```ruby -windows_package 'PuTTY version 0.60' do - source 'http://the.earth.li/~sgtatham/putty/latest/x86/putty-0.60-installer.exe' - installer_type :inno - action :install -end -``` - -Install 7-Zip (MSI installer) -```ruby -windows_package '7-Zip 9.20 (x64 edition)' do - source 'http://downloads.sourceforge.net/sevenzip/7z920-x64.msi' - action :install -end -``` - -Install Notepad++ (Y U No Emacs?) using a local installer -```ruby -windows_package 'Notepad++' do - source 'c:/installation_files/npp.5.9.2.Installer.exe' - action :install -end -``` - -Install VLC for that Xvid (NSIS installer) -```ruby -windows_package 'VLC media player 1.1.10' do - source 'http://superb-sea2.dl.sourceforge.net/project/vlc/1.1.10/win32/vlc-1.1.10-win32.exe' - action :install -end -``` - -Install Firefox as custom installer and manually set the silent install flags -```ruby -windows_package 'Mozilla Firefox 5.0 (x86 en-US)' do - source 'http://archive.mozilla.org/pub/mozilla.org/mozilla.org/firefox/releases/5.0/win32/en-US/Firefox%20Setup%205.0.exe' - options '-ms' - installer_type :custom - action :install -end -``` - -Google Chrome FTW (MSI installer) -```ruby -windows_package 'Google Chrome' do - source 'https://dl-ssl.google.com/tag/s/appguid%3D%7B8A69D345-D564-463C-AFF1-A69D9E530F96%7D%26iid%3D%7B806F36C0-CB54-4A84-A3F3-0CF8A86575E0%7D%26lang%3Den%26browser%3D3%26usagestats%3D0%26appname%3DGoogle%2520Chrome%26needsadmin%3Dfalse/edgedl/chrome/install/GoogleChromeStandaloneEnterprise.msi' - action :install -end -``` - -Remove Google Chrome -```ruby -windows_package 'Google Chrome' do - action :remove -end -``` - -Remove 7-Zip -```ruby -windows_package '7-Zip 9.20 (x64 edition)' do - action :remove -end -``` - -### windows_printer_port - -Create and delete TCP/IPv4 printer ports. - -#### Actions -- `:create` - Create a TCIP/IPv4 printer port. This is the default action. -- `:delete` - Delete a TCIP/IPv4 printer port - -#### Attribute Parameters -- `ipv4_address` - Name attribute. Required. IPv4 address, e.g. '10.0.24.34' -- `port_name` - Port name. Optional. Defaults to 'IP_' + `ipv4_address` -- `port_number` - Port number. Optional. Defaults to 9100. -- `port_description` - Port description. Optional. -- `snmp_enabled` - Boolean. Optional. Defaults to false. -- `port_protocol` - Port protocol, 1 (RAW), or 2 (LPR). Optional. Defaults to 1. - -#### Examples - -Create a TCP/IP printer port named 'IP_10.4.64.37' with all defaults -```ruby -windows_printer_port '10.4.64.37' do - action :create -end -``` - -Delete a printer port -```ruby -windows_printer_port '10.4.64.37' do - action :delete -end -``` - -Delete a port with a custom port_name -```ruby -windows_printer_port '10.4.64.38' do - port_name 'My awesome port' - action :delete -end -``` - -Create a port with more options -```ruby -windows_printer_port '10.4.64.39' do - port_name 'My awesome port' - snmp_enabled true - port_protocol 2 -end -``` - -### windows_printer - -Create Windows printer. Note that this doesn't currently install a printer -driver. You must already have the driver installed on the system. - -The Windows Printer LWRP will automatically create a TCP/IP printer port for you using the `ipv4_address` property. If you want more granular control over the printer port, just create it using the `windows_printer_port` LWRP before creating the printer. - -#### Actions -- `:create` - Create a new printer -- `:delete` - Delete a new printer - -#### Attribute Parameters -- `device_id` - Name attribute. Required. Printer queue name, e.g. 'HP LJ 5200 in fifth floor copy room' -- `comment` - Optional string describing the printer queue. -- `default` - Boolean. Optional. Defaults to false. Note that Windows sets the first printer defined to the default printer regardless of this setting. -- `driver_name` - String. Required. Exact name of printer driver. Note that the printer driver must already be installed on the node. -- `location` - Printer location, e.g. 'Fifth floor copy room', or 'US/NYC/Floor42/Room4207' -- `shared` - Boolean. Defaults to false. -- `share_name` - Printer share name. -- `ipv4_address` - Printer IPv4 address, e.g. '10.4.64.23'. You don't have to be able to ping the IP addresss to set it. Required. - -An error of "Set-WmiInstance : Generic failure" is most likely due to the printer driver name not matching or not being installed. - -#### Examples - -Create a printer -```ruby -windows_printer 'HP LaserJet 5th Floor' do - driver_name 'HP LaserJet 4100 Series PCL6' - ipv4_address '10.4.64.38' -end -``` - -Delete a printer. Note: this doesn't delete the associated printer port. See `windows_printer_port` above for how to delete the port. -```ruby -windows_printer 'HP LaserJet 5th Floor' do - action :delete -end -``` - -### windows_reboot -This resource is now deprecated and will be removed in a future version of this cookbook. Chef >= 12.0.0 includes a built-in [reboot](http://docs.chef.io/resource_reboot.html) resource. - -Sets required data in the node's run_state to notify `WindowsRebootHandler` a reboot is requested. If Chef run completes successfully a reboot will occur if the `WindowsRebootHandler` is properly registered as a report handler. As an action of `:request` will cause a node to reboot every Chef run, this resource is usually notified by other resources...ie restart node after a package is installed (see example below). - -#### Actions -- `:request` - requests a reboot at completion of successful Cher run. requires `WindowsRebootHandler` to be registered as a report handler. -- `:cancel` - remove reboot request from node.run_state. this will cancel *ALL* previously requested reboots as this is a binary state. - -#### Attribute Parameters -- `timeout` - Name attribute. timeout delay in seconds to wait before proceeding with the requested reboot. default is 60 seconds -- `reason` - comment on the reason for the reboot. default is 'Chef Software Chef initiated reboot' - -#### Examples -If the package installs, schedule a reboot at end of chef run -```ruby -windows_reboot 60 do - reason 'cause chef said so' - action :nothing -end - -windows_package 'some_package' do - action :install - notifies :request, 'windows_reboot[60]' -end -``` - -Cancel the previously requested reboot -```ruby -windows_reboot 60 do - action :cancel -end -``` - -### windows_registry -This resource is now deprecated and will be removed in a future version of this cookbook. Chef >= 11.6.0 includes a built-in [registry_key](http://docs.chef.io/resource_registry_key.html) resource. - -Creates and modifies Windows registry keys. - -*Change in v1.3.0: The Win32 classes use `::Win32` to avoid namespace conflict with `Chef::Win32` (introduced in Chef 0.10.10).* - -#### Actions -- `:create` - create a new registry key with the provided values. -- `:modify` - modify an existing registry key with the provided values. -- `:force_modify` - modify an existing registry key with the provided values. ensures the value is actually set by checking multiple times. useful for fighting race conditions where two processes are trying to set the same registry key. This will be updated in the near future to use 'RegNotifyChangeKeyValue' which is exposed by the WinAPI and allows a process to register for notification on a registry key change. -- `:remove` - removes a value from an existing registry key - -#### Attribute Parameters -- `key_name` - name attribute. The registry key to create/modify. -- `values` - hash of the values to set under the registry key. The individual hash items will become respective 'Value name' => 'Value data' items in the registry key. -- `type` - Type of key to create, defaults to REG_SZ. Must be a symbol, see the overview below for valid values. - -#### Registry key types -- `:binary` - REG_BINARY -- `:string` - REG_SZ -- `:multi_string` - REG_MULTI_SZ -- `:expand_string` - REG_EXPAND_SZ -- `:dword` - REG_DWORD -- `:dword_big_endian` - REG_DWORD_BIG_ENDIAN -- `:qword` - REG_QWORD - -#### Examples - -Make the local windows proxy match the one set for Chef -```ruby -proxy = URI.parse(Chef::Config[:http_proxy]) -windows_registry 'HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings' do - values 'ProxyEnable' => 1, 'ProxyServer' => "#{proxy.host}:#{proxy.port}", 'ProxyOverride' => '' -end -``` - -Enable Remote Desktop and poke the firewall hole -```ruby -windows_registry 'HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server' do - values 'FdenyTSConnections' => 0 -end -``` - -Delete an item from the registry -```ruby -windows_registry 'HKCU\Software\Test' do - #Key is the name of the value that you want to delete the value is always empty - values 'ValueToDelete' => '' - action :remove -end -``` - -Add a REG_MULTI_SZ value to the registry -```ruby -windows_registry 'HKCU\Software\Test' do - values 'MultiString' => ['line 1', 'line 2', 'line 3'] - type :multi_string -end -``` - -### windows_shortcut -Creates and modifies Windows shortcuts. - -#### Actions -- `:create` - create or modify a windows shortcut - -#### Attribute Parameters -- `name` - name attribute. The shortcut to create/modify. -- `target` - what the shortcut links to -- `arguments` - arguments to pass to the target when the shortcut is executed -- `description` - description of the shortcut -- `cwd` - Working directory to use when the target is executed -- `iconlocation` - Icon to use, in the format of ```"path, index"``` where index is which icon in that file to use (See [WshShortcut.IconLocation](https://msdn.microsoft.com/en-us/library/3s9bx7at.aspx)) - -#### Examples - -Add a shortcut all users desktop: -```ruby -require 'win32ole' -all_users_desktop = WIN32OLE.new("WScript.Shell").SpecialFolders("AllUsersDesktop") - -windows_shortcut "#{all_users_desktop}/Notepad.lnk" do - target "C:\\WINDOWS\\notepad.exe" - description "Launch Notepad" - iconlocation "C:\\windows\\notepad.exe, 0" -end -``` - -#### Library Methods - -```ruby -Registry.value_exists?('HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run','BGINFO') -Registry.key_exists?('HKLM\SOFTWARE\Microsoft') -BgInfo = Registry.get_value('HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run','BGINFO') -``` - -### windows_path -#### Actions -- `:add` - Add an item to the system path -- `:remove` - Remove an item from the system path - -#### Attribute Parameters -- `path` - Name attribute. The name of the value to add to the system path - -#### Examples - -Add Sysinternals to the system path -```ruby -windows_path 'C:\Sysinternals' do - action :add -end -``` - -Remove 7-Zip from the system path -```ruby -windows_path 'C:\7-Zip' do - action :remove -end -``` - -### windows_task -Creates, deletes or runs a Windows scheduled task. Requires Windows -Server 2008 due to API usage. - -#### Actions -- `:create` - creates a task (or updates existing if user or command has changed) -- `:delete` - deletes a task -- `:run` - runs a task -- `:end` - ends a task -- `:change` - changes the un/pw or command of a task -- `:enable` - enable a task -- `:disable` - disable a task - -#### Attribute Parameters -- `task_name` - name attribute, The task name. ("Task Name" or "/Task Name") -- `force` - When used with create, will update the task. -- `command` - The command the task will run. -- `cwd` - The directory the task will be run from. -- `user` - The user to run the task as. (defaults to 'SYSTEM') -- `password` - The user's password. (requires user) -- `run_level` - Run with `:limited` or `:highest` privileges. -- `frequency` - Frequency with which to run the task. (default is :hourly. Other valid values include :minute, :hourly, :daily, :weekly, :monthly, :once, :on_logon, :onstart, :on_idle) \*:once requires start_time -- `frequency_modifier` - Multiple for frequency. (15 minutes, 2 days) -- `start_day` - Specifies the first date on which the task runs. Optional string (MM/DD/YYYY) -- `start_time` - Specifies the start time to run the task. Optional string (HH:mm) -- `interactive_enabled` - (Allow task to run interactively or non-interactively. Requires user and password.) -- `day` - For monthly or weekly tasks, the day(s) on which the task runs. (MON - SUN, *, 1 - 31) - -#### Examples - -Create a `chef-client` task with TaskPath `\` running every 15 minutes -```ruby -windows_task 'chef-client' do - user 'Administrator' - password '$ecR3t' - cwd 'C:\\chef\\bin' - command 'chef-client -L C:\\tmp\\' - run_level :highest - frequency :minute - frequency_modifier 15 -end -``` - -Update `chef-client` task with new password and log location -```ruby -windows_task 'chef-client' do - user 'Administrator' - password 'N3wPassW0Rd' - cwd 'C:\\chef\\bin' - command 'chef-client -L C:\\chef\\logs\\' - action :change -end -``` - -Delete a taks named `old task` -```ruby -windows_task 'old task' do - action :delete -end -``` - -Enable a task named `chef-client` -```ruby -windows_task 'chef-client' do - action :enable -end -``` - -Disable a task named `ProgramDataUpdater` with TaskPath `\Microsoft\Windows\Application Experience\` -```ruby -windows_task '\Microsoft\Windows\Application Experience\ProgramDataUpdater' do - action :disable -end -``` - -### windows_zipfile -Most version of Windows do not ship with native cli utility for managing compressed files. This resource provides a pure-ruby implementation for managing zip files. Be sure to use the `not_if` or `only_if` meta parameters to guard the resource for idempotence or action will be taken every Chef run. - -#### Actions -- `:unzip` - unzip a compressed file -- `:zip` - zip a directory (recursively) - -#### Attribute Parameters -- `path` - name attribute. The path where files will be (un)zipped to. -- `source` - source of the zip file (either a URI or local path) for :unzip, or directory to be zipped for :zip. -- `overwrite` - force an overwrite of the files if they already exist. -- `checksum` - for :unzip, useful if source is remote, if the local file matches the SHA-256 checksum, Chef will not download it. - -#### Examples - -Unzip a remote zip file locally -```ruby -windows_zipfile 'c:/bin' do - source 'http://download.sysinternals.com/Files/SysinternalsSuite.zip' - action :unzip - not_if {::File.exists?('c:/bin/PsExec.exe')} -end -``` - -Unzip a local zipfile -```ruby -windows_zipfile 'c:/the_codez' do - source 'c:/foo/baz/the_codez.zip' - action :unzip -end -``` - -Create a local zipfile -```ruby -windows_zipfile 'c:/foo/baz/the_codez.zip' do - source 'c:/the_codez' - action :zip -end -``` - -Libraries -------------------------- -### WindowsHelper - -Helper that allows you to use helpful functions in windows - -#### installed_packages -Returns a hash of all DisplayNames installed -```ruby -# usage in a recipe -::Chef::Recipe.send(:include, Windows::Helper) -hash_of_installed_packages = installed_packages -``` - -#### is_package_installed? -- `package_name` - The name of the package you want to query to see if it is installed -- `returns` - true if the package is installed, false if it the package is not installed - -Download a file if a package isn't installed -```ruby -# usage in a recipe to not download a file if package is already installed -::Chef::Recipe.send(:include, Windows::Helper) -is_win_sdk_installed = is_package_installed?('Windows Software Development Kit') - -remote_file 'C:\windows\temp\windows_sdk.zip' do - source 'http://url_to_download/windows_sdk.zip' - action :create_if_missing - not_if {is_win_sdk_installed} -end -``` -Do something if a package is installed -```ruby -# usage in a provider -include Windows::Helper -if is_package_installed?('Windows Software Development Kit') - # do something if package is installed -end -``` - -Exception/Report Handlers -------------------------- -### WindowsRebootHandler -Required reboots are a necessary evil of configuring and managing Windows nodes. This report handler (ie fires at the end of Chef runs) acts on requested (Chef initiated) or pending (as determined by the OS per configuration action we performed) reboots. The `allow_pending_reboots` initialization argument should be set to false if you do not want the handler to automatically reboot a node if it has been determined a reboot is pending. Reboots can still be requested explicitly via the `windows_reboot` LWRP. - -### Initialization Arguments -- `allow_pending_reboots` - indicator on whether the handler should act on a the Window's 'pending reboot' state. default is true -- `timeout` - timeout delay in seconds to wait before proceeding with the reboot. default is 60 seconds -- `reason` - comment on the reason for the reboot. default is 'Chef Software Chef initiated reboot' - - -Windows ChefSpec Matchers -------------------------- -The Windows cookbook includes custom [ChefSpec](https://github.com/sethvargo/chefspec) matchers you can use to test your own cookbooks that consume Windows cookbook LWRPs. - -###Example Matcher Usage -```ruby -expect(chef_run).to install_windows_package('Node.js').with( - source: 'http://nodejs.org/dist/v0.10.26/x64/node-v0.10.26-x64.msi') -``` - -###Windows Cookbook Matchers -* install_windows_package -* remove_windows_package -* install_windows_feature -* remove_windows_feature -* delete_windows_feature -* create_windows_task -* delete_windows_task -* run_windows_task -* change_windows_task -* add_windows_path -* remove_windows_path -* run_windows_batch -* set_windows_pagefile -* unzip_windows_zipfile_to -* zip_windows_zipfile_to -* create_windows_shortcut -* create_windows_auto_run -* remove_windows_auto_run -* create_windows_printer -* delete_windows_printer -* create_windows_printer_port -* delete_windows_printer_port -* request_windows_reboot -* cancel_windows_reboot -* create_windows_shortcut - - -Usage ------ - -Place an explicit dependency on this cookbook (using depends in the cookbook's metadata.rb) from any cookbook where you would like to use the Windows-specific resources/providers that ship with this cookbook. - -```ruby -depends 'windows' -``` - -### default -Convenience recipe that installs supporting gems for many of the resources/providers that ship with this cookbook. - -### reboot_handler -Leverages the `chef_handler` LWRP to register the `WindowsRebootHandler` report handler that ships as part of this cookbook. By default this handler is set to automatically act on pending reboots. If you would like to change this behavior override `node['windows']['allow_pending_reboots']` and set the value to false. For example: - -```ruby -name 'base' -description 'base role' -override_attributes( - 'windows' => { - 'allow_pending_reboots' => false - } -) -``` - -This will still allow a reboot to be explicitly requested via the `windows_reboot` LWRP. - -By default, the handler will only be registered as a report handler, meaning that it will only fire at the end of successful Chef runs. If the run fails, pending or requested reboots will be ignored. This can lead to a situation where some package was installed and notified a reboot request via the `windows_reboot` LWRP, and then the run fails for some unrelated reason, and the reboot request gets dropped because the resource that notified the reboot request will already be up-to-date at the next run and will not request a reboot again, and thus the requested reboot will never be performed. To change this behavior and register the handler as an exception handler that fires at the end of failed runs too, override `node['windows']['allow_reboot_on_failure']` and set the value to true. - - -License & Authors ------------------ -- Author:: Seth Chisamore () -- Author:: Doug MacEachern () -- Author:: Paul Morton () -- Author:: Doug Ireton () - -```text -Copyright 2011-2015, Chef Software, Inc. -Copyright 2010, VMware, Inc. -Copyright 2011, Business Intelligence Associates, Inc -Copyright 2012, Nordstrom, Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -``` +# Windows Cookbook + +[![Build status](https://ci.appveyor.com/api/projects/status/9x4uepmm1g4rktie/branch/master?svg=true)](https://ci.appveyor.com/project/ChefWindowsCookbooks/windows/branch/master) [![Cookbook Version](https://img.shields.io/cookbook/v/windows.svg)](https://supermarket.chef.io/cookbooks/windows) + +Provides a set of Windows-specific resources to aid in the creation of cookbooks/recipes targeting the Windows platform. + +## Requirements + +### Platforms + +- Windows 7 +- Windows Server 2008 R2 +- Windows 8, 8.1 +- Windows Server 2012 (R1, R2) + +### Chef + +- Chef 12.6+ + +## Resources + +### windows_auto_run + +#### Actions + +- `:create` - Create an item to be run at login +- `:remove` - Remove an item that was previously setup to run at login + +#### Properties + +- `name` - Name attribute. The name of the value to be stored in the registry +- `program` - The program to be run at login +- `args` - The arguments for the program + +#### Examples + +Run BGInfo at login + +```ruby +windows_auto_run 'BGINFO' do + program 'C:/Sysinternals/bginfo.exe' + args '\'C:/Sysinternals/Config.bgi\' /NOLICPROMPT /TIMER:0' + action :create +end +``` + +### windows_certificate + +Installs a certificate into the Windows certificate store from a file, and grants read-only access to the private key for designated accounts. Due to current limitations in WinRM, installing certificated remotely may not work if the operation requires a user profile. Operations on the local machine store should still work. + +#### Actions + +- `:create` - creates or updates a certificate. +- `:delete` - deletes a certificate. +- `:acl_add` - adds read-only entries to a certificate's private key ACL. + +#### Properties + +- `source` - name attribute. The source file (for create and acl_add), thumbprint (for delete and acl_add) or subject (for delete). +- `pfx_password` - the password to access the source if it is a pfx file. +- `private_key_acl` - array of 'domain\account' entries to be granted read-only access to the certificate's private key. This is not idempotent. +- `store_name` - the certificate store to manipulate. One of MY (default : personal store), CA (trusted intermediate store) or ROOT (trusted root store). +- `user_store` - if false (default) then use the local machine store; if true then use the current user's store. + +#### Examples + +```ruby +# Add PFX cert to local machine personal store and grant accounts read-only access to private key +windows_certificate "c:/test/mycert.pfx" do + pfx_password "password" + private_key_acl ["acme\fred", "pc\jane"] +end +``` + +```ruby +# Add cert to trusted intermediate store +windows_certificate "c:/test/mycert.cer" do + store_name "CA" +end +``` + +```ruby +# Remove all certificates matching the subject +windows_certificate "me.acme.com" do + action :delete +end +``` + +### windows_certificate_binding + +Binds a certificate to an HTTP port in order to enable TLS communication. + +#### Actions + +- `:create` - creates or updates a binding. +- `:delete` - deletes a binding. + +#### Properties + +- `cert_name` - name attribute. The thumbprint(hash) or subject that identifies the certificate to be bound. +- `name_kind` - indicates the type of cert_name. One of :subject (default) or :hash. +- `address` - the address to bind against. Default is 0.0.0.0 (all IP addresses). +- `port` - the port to bind against. Default is 443. +- `app_id` - the GUID that defines the application that owns the binding. Default is the values used by IIS. +- `store_name` - the store to locate the certificate in. One of MY (default : personal store), CA (trusted intermediate store) or ROOT (trusted root store). + +#### Examples + +```ruby +# Bind the first certificate matching the subject to the default TLS port +windows_certificate_binding "me.acme.com" do +end +``` + +```ruby +# Bind a cert from the CA store with the given hash to port 4334 +windows_certificate_binding "me.acme.com" do + cert_name "d234567890a23f567c901e345bc8901d34567890" + name_kind :hash + store_name "CA" + port 4334 +end +``` + +### windows_feature + +**BREAKING CHANGE - Version 3.0.0** + +This resource has been moved from using LWRPs and multiple providers to using Custom Resources. To maintain functionality, you'll need to change `provider` to `install_method`. + +Windows Roles and Features can be thought of as built-in operating system packages that ship with the OS. A server role is a set of software programs that, when they are installed and properly configured, lets a computer perform a specific function for multiple users or other computers within a network. A Role can have multiple Role Services that provide functionality to the Role. Role services are software programs that provide the functionality of a role. Features are software programs that, although they are not directly parts of roles, can support or augment the functionality of one or more roles, or improve the functionality of the server, regardless of which roles are installed. Collectively we refer to all of these attributes as 'features'. + +This resource allows you to manage these 'features' in an unattended, idempotent way. + +There are three methods for the `windows_feature` which map into Microsoft's three major tools for managing roles/features: [Deployment Image Servicing and Management (DISM)](http://msdn.microsoft.com/en-us/library/dd371719%28v=vs.85%29.aspx), [Servermanagercmd](http://technet.microsoft.com/en-us/library/ee344834%28WS.10%29.aspx) (The CLI for Server Manager), and [PowerShell](https://technet.microsoft.com/en-us/library/cc731774(v=ws.11).aspx). As Servermanagercmd is deprecated, Chef will set the default method to `:windows_feature_dism` if `dism.exe` is present on the system being configured. The default method will fall back to `:windows_feature_servermanagercmd`, and then `:windows_feature_powershell`. + +For more information on Roles, Role Services and Features see the [Microsoft TechNet article on the topic](http://technet.microsoft.com/en-us/library/cc754923.aspx). For a complete list of all features that are available on a node type either of the following commands at a command prompt: + +For Dism: + +```text +dism /online /Get-Features +``` + +For ServerManagerCmd: + +```text +servermanagercmd -query +``` + +For PowerShell: + +```text +get-windowsfeature +``` + +#### Actions + +- `:install` - install a Windows role/feature +- `:remove` - remove a Windows role/feature +- `:delete` - remove a Windows role/feature from the image (not supported by ServerManagerCmd) + +#### Properties + +- `feature_name` - name of the feature/role(s) to install. The same feature may have different names depending on the provider used (ie DHCPServer vs DHCP; DNS-Server-Full-Role vs DNS). +- `all` - Boolean. Optional. Default: false. DISM and Powershell providers only. Forces all dependencies to be installed. +- `source` - String. Optional. DISM provider only. Uses local repository for feature install. +- `install_method` - Symbol. Optional. **REPLACEMENT FOR THE PREVIOUS PROVIDER OPTION** If not supplied, Chef will determine which method to use (in the order of `:windows_feature_dism`, `:windows_feature_servercmd`, `:windows_feature_powershell`) + +#### Examples + +Install the DHCP Server feature + +```ruby +windows_feature 'DHCPServer' do + action :install +end +``` + +Install the .Net 3.5.1 feature on Server 2012 using repository files on DVD and install all dependencies + +```ruby +windows_feature "NetFx3" do + action :install + all true + source "d:\sources\sxs" +end +``` + +Remove Telnet Server and Client features + +```ruby +windows_feature ['TelnetServer', 'TelnetClient'] do + action :remove +end +``` + +Add the SMTP Server feature using the PowerShell provider + +```ruby +windows_feature "smtp-server" do + action :install + all true + install_method :windows_feature_powershell +end +``` + +Install multiple features using one resource with the PowerShell provider + +```ruby +windows_feature ['Web-Asp-Net45', 'Web-Net-Ext45'] do + action :install + install_method :windows_feature_powershell +end +``` + +### windows_font + +Installs a font. + +Font files should be included in the cookbooks + +#### Actions + +- `:install` - install a font to the system fonts directory. + +#### Properties + +- `name` - The file name of the font file name to install. The path defaults to the files/default directory of the cookbook you're calling windows_font from. Defaults to the resource name. +- `source` - Set an alternate path to the font file. + +#### Examples + +```ruby +windows_font 'Code New Roman.otf' +``` + +### windows_http_acl + +Sets the Access Control List for an http URL to grant non-admin accounts permission to open HTTP endpoints. + +#### Actions + +- `:create` - creates or updates the ACL for a URL. +- `:delete` - deletes the ACL from a URL. + +#### Properties + +- `url` - the name of the url to be created/deleted. +- `sddl` - the DACL string configuring all permissions to URL. Mandatory for create if user is not provided. Can't be use with `user`. +- `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. + +#### Examples + +```ruby +windows_http_acl 'http://+:50051/' do + user 'pc\\fred' +end +``` + +```ruby +# Grant access to users "NT SERVICE\WinRM" and "NT SERVICE\Wecsvc" via sddl +windows_http_acl 'http://+:5985/' do + sddl 'D:(A;;GX;;;S-1-5-80-569256582-2953403351-2909559716-1301513147-412116970)(A;;GX;;;S-1-5-80-4059739203-877974739-1245631912-527174227-2996563517)' +end +``` + +```ruby +windows_http_acl 'http://+:50051/' do + action :delete +end +``` + +### windows_pagefile + +Configures the file that provides virtual memory for applications requiring more memory than available RAM or that are paged out to free up memory in use. + + +#### Actions + +- `:set` - configures the default pagefile, creating if it doesn't exist. +- `:delete` - deletes the specified pagefile. + +#### Properties + +- `name` - the path to the pagefile, String, name_property: true +- `system_managed` - configures whether the system manages the pagefile size. [true, false] +- `automatic_managed` - all of the settings are managed by the system. If this is set to true, other settings will be ignored. [true, false], default: false +- `initial_size` - initial size of the pagefile in bytes. Integer +- `maximum_size` - maximum size of the pagefile in bytes. Integer + +### windows_printer_port + +Create and delete TCP/IPv4 printer ports. + +#### Actions + +- `:create` - Create a TCIP/IPv4 printer port. This is the default action. +- `:delete` - Delete a TCIP/IPv4 printer port + +#### Properties + +- `ipv4_address` - Name attribute. Required. IPv4 address, e.g. '10.0.24.34' +- `port_name` - Port name. Optional. Defaults to 'IP_' + `ipv4_address` +- `port_number` - Port number. Optional. Defaults to 9100. +- `port_description` - Port description. Optional. +- `snmp_enabled` - Boolean. Optional. Defaults to false. +- `port_protocol` - Port protocol, 1 (RAW), or 2 (LPR). Optional. Defaults to 1. + +#### Examples + +Create a TCP/IP printer port named 'IP_10.4.64.37' with all defaults + +```ruby +windows_printer_port '10.4.64.37' do + action :create +end +``` + +Delete a printer port + +```ruby +windows_printer_port '10.4.64.37' do + action :delete +end +``` + +Delete a port with a custom port_name + +```ruby +windows_printer_port '10.4.64.38' do + port_name 'My awesome port' + action :delete +end +``` + +Create a port with more options + +```ruby +windows_printer_port '10.4.64.39' do + port_name 'My awesome port' + snmp_enabled true + port_protocol 2 +end +``` + +### windows_printer + +Create Windows printer. Note that this doesn't currently install a printer driver. You must already have the driver installed on the system. + +The Windows Printer LWRP will automatically create a TCP/IP printer port for you using the `ipv4_address` property. If you want more granular control over the printer port, just create it using the `windows_printer_port` LWRP before creating the printer. + +#### Actions + +- `:create` - Create a new printer +- `:delete` - Delete a new printer + +#### Properties + +- `device_id` - Name attribute. Required. Printer queue name, e.g. 'HP LJ 5200 in fifth floor copy room' +- `comment` - Optional string describing the printer queue. +- `default` - Boolean. Optional. Defaults to false. Note that Windows sets the first printer defined to the default printer regardless of this setting. +- `driver_name` - String. Required. Exact name of printer driver. Note that the printer driver must already be installed on the node. +- `location` - Printer location, e.g. 'Fifth floor copy room', or 'US/NYC/Floor42/Room4207' +- `shared` - Boolean. Defaults to false. +- `share_name` - Printer share name. +- `ipv4_address` - Printer IPv4 address, e.g. '10.4.64.23'. You don't have to be able to ping the IP address to set it. Required. + +An error of "Set-WmiInstance : Generic failure" is most likely due to the printer driver name not matching or not being installed. + +#### Examples + +Create a printer + +```ruby +windows_printer 'HP LaserJet 5th Floor' do + driver_name 'HP LaserJet 4100 Series PCL6' + ipv4_address '10.4.64.38' +end +``` + +Delete a printer. Note: this doesn't delete the associated printer port. See `windows_printer_port` above for how to delete the port. + +```ruby +windows_printer 'HP LaserJet 5th Floor' do + action :delete +end +``` + +### windows_share + +Creates, modifies and removes Windows shares. All properties are idempotent. + +#### Actions + +- :create: creates/modifies a share +- :delete: deletes a share + +#### Properties + +- share_name: name attribute, the share name. +- path: path to the directory to be shared. Required when creating. If the share already exists on a different path then it is deleted and re-created. +- description: description to be applied to the share +- full_users: array of users which should have "Full control" permissions +- change_users: array of users which should have "Change" permissions +- read_users: array of users which should have "Read" permissions + +#### Examples + +```ruby +windows_share "foo" do + action :create + path "C:\\foo" + full_users ["DOMAIN_A\\some_user", "DOMAIN_B\\some_other_user"] + read_users ["DOMAIN_C\\Domain users"] +end +``` + +```ruby +windows_share "foo" do + action :delete +end +``` + +### windows_shortcut + +Creates and modifies Windows shortcuts. + +#### Actions + +- `:create` - create or modify a windows shortcut + +#### Properties + +- `name` - name attribute. The shortcut to create/modify. +- `target` - what the shortcut links to +- `arguments` - arguments to pass to the target when the shortcut is executed +- `description` - description of the shortcut +- `cwd` - Working directory to use when the target is executed +- `iconlocation` - Icon to use, in the format of `"path, index"` where index is which icon in that file to use (See [WshShortcut.IconLocation](https://msdn.microsoft.com/en-us/library/3s9bx7at.aspx)) + +#### Examples + +Add a shortcut all users desktop: + +```ruby +require 'win32ole' +all_users_desktop = WIN32OLE.new("WScript.Shell").SpecialFolders("AllUsersDesktop") + +windows_shortcut "#{all_users_desktop}/Notepad.lnk" do + target "C:\\WINDOWS\\notepad.exe" + description "Launch Notepad" + iconlocation "C:\\windows\\notepad.exe, 0" +end +``` + +#### Library Methods + +```ruby +Registry.value_exists?('HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run','BGINFO') +Registry.key_exists?('HKLM\SOFTWARE\Microsoft') +BgInfo = Registry.get_value('HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run','BGINFO') +``` + +### windows_path + +#### Actions + +- `:add` - Add an item to the system path +- `:remove` - Remove an item from the system path + +#### Properties + +- `path` - Name attribute. The name of the value to add to the system path + +#### Examples + +Add Sysinternals to the system path + +```ruby +windows_path 'C:\Sysinternals' do + action :add +end +``` + +Remove 7-Zip from the system path + +```ruby +windows_path 'C:\7-Zip' do + action :remove +end +``` + +### windows_task + +Creates, deletes or runs a Windows scheduled task. Requires Windows Server 2008 due to API usage. + +#### Actions + +- `:create` - creates a task (or updates existing if user or command has changed) +- `:delete` - deletes a task +- `:run` - runs a task +- `:end` - ends a task +- `:change` - changes the un/pw or command of a task +- `:enable` - enable a task +- `:disable` - disable a task + +#### Properties + +- `task_name` - name attribute, The task name. ("Task Name" or "/Task Name") +- `force` - When used with create, will update the task. +- `command` - The command the task will run. +- `cwd` - The directory the task will be run from. +- `user` - The user to run the task as. (defaults to 'SYSTEM') +- `password` - The user's password. (requires user) +- `run_level` - Run with `:limited` or `:highest` privileges. +- `frequency` - Frequency with which to run the task. (default is :hourly. Other valid values include :minute, :hourly, :daily, :weekly, :monthly, :once, :on_logon, :onstart, :on_idle) :once requires start_time +- `frequency_modifier` - Multiple for frequency. (15 minutes, 2 days). Monthly tasks may also use these values": ('FIRST', 'SECOND', 'THIRD', 'FOURTH', 'LAST', 'LASTDAY') +- `start_day` - Specifies the first date on which the task runs. Optional string (MM/DD/YYYY) +- `start_time` - Specifies the start time to run the task. Optional string (HH:mm) +- `interactive_enabled` - (Allow task to run interactively or non-interactively. Requires user and password.) +- `day` - For monthly or weekly tasks, the day(s) on which the task runs. (MON - SUN, *, 1 - 31) +- `months` - The Months of the year on which the task runs. (JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC, *). Multiple months should be comma delimited. +- `idle_time` - For :on_idle frequency, the time (in minutes) without user activity that must pass to trigger the task. (1 - 999) + +#### Examples + +Create a `chef-client` task with TaskPath `\` running every 15 minutes + +```ruby +windows_task 'chef-client' do + user 'Administrator' + password '$ecR3t' + cwd 'C:\\chef\\bin' + command 'chef-client -L C:\\tmp\\' + run_level :highest + frequency :minute + frequency_modifier 15 +end +``` + +Update `chef-client` task with new password and log location + +```ruby +windows_task 'chef-client' do + user 'Administrator' + password 'N3wPassW0Rd' + cwd 'C:\\chef\\bin' + command 'chef-client -L C:\\chef\\logs\\' + action :change +end +``` + +Delete a task named `old task` + +```ruby +windows_task 'old task' do + action :delete +end +``` + +Enable a task named `chef-client` + +```ruby +windows_task 'chef-client' do + action :enable +end +``` + +Disable a task named `ProgramDataUpdater` with TaskPath `\Microsoft\Windows\Application Experience\` + +```ruby +windows_task '\Microsoft\Windows\Application Experience\ProgramDataUpdater' do + action :disable +end +``` + +### windows_zipfile + +Most version of Windows do not ship with native cli utility for managing compressed files. This resource provides a pure-ruby implementation for managing zip files. Be sure to use the `not_if` or `only_if` meta parameters to guard the resource for idempotence or action will be taken every Chef run. + +#### Actions + +- `:unzip` - unzip a compressed file +- `:zip` - zip a directory (recursively) + +#### Properties + +- `path` - name attribute. The path where files will be (un)zipped to. +- `source` - source of the zip file (either a URI or local path) for :unzip, or directory to be zipped for :zip. +- `overwrite` - force an overwrite of the files if they already exist. +- `checksum` - for :unzip, useful if source is remote, if the local file matches the SHA-256 checksum, Chef will not download it. + +#### Examples + +Unzip a remote zip file locally + +```ruby +windows_zipfile 'c:/bin' do + source 'http://download.sysinternals.com/Files/SysinternalsSuite.zip' + action :unzip + not_if {::File.exists?('c:/bin/PsExec.exe')} +end +``` + +Unzip a local zipfile + +```ruby +windows_zipfile 'c:/the_codez' do + source 'c:/foo/baz/the_codez.zip' + action :unzip +end +``` + +Create a local zipfile + +```ruby +windows_zipfile 'c:/foo/baz/the_codez.zip' do + source 'c:/the_codez' + action :zip +end +``` + +## Libraries + +### WindowsHelper + +Helper that allows you to use helpful functions in windows + +#### installed_packages + +Returns a hash of all DisplayNames installed + +```ruby +# usage in a recipe +::Chef::Recipe.send(:include, Windows::Helper) +hash_of_installed_packages = installed_packages +``` + +#### is_package_installed? + +- `package_name` - The name of the package you want to query to see if it is installed +- `returns` - true if the package is installed, false if it the package is not installed + +Download a file if a package isn't installed + +```ruby +# usage in a recipe to not download a file if package is already installed +::Chef::Recipe.send(:include, Windows::Helper) +is_win_sdk_installed = is_package_installed?('Windows Software Development Kit') + +remote_file 'C:\windows\temp\windows_sdk.zip' do + source 'http://url_to_download/windows_sdk.zip' + action :create_if_missing + not_if {is_win_sdk_installed} +end +``` + +Do something if a package is installed + +```ruby +# usage in a provider +include Windows::Helper +if is_package_installed?('Windows Software Development Kit') + # do something if package is installed +end +``` + +### Windows::VersionHelper + +Helper that allows you to get information of the windows version running on your node. It leverages windows ohai from kernel.os_info, easy to mock and to use even on linux. + +#### core_version? + +Determines whether given node is running on a windows Core. + +```ruby +if ::Windows::VersionHelper.core_version? node + fail 'Windows Core is not supported' +end +``` + +#### workstation_version? + +Determines whether given node is a windows workstation version (XP, Vista, 7, 8, 8.1, 10) + +```ruby +if ::Windows::VersionHelper.workstation_version? node + fail 'Only server version of windows are supported' +end +``` + +#### server_version? + +Determines whether given node is a windows server version (Server 2003, Server 2008, Server 2012, Server 2016) + +```ruby +if ::Windows::VersionHelper.server_version? node + puts 'Server version of windows are cool' +end +``` + +#### nt_version + +Determines NT version of the given node + +```ruby +case ::Windows::VersionHelper.nt_version node + when '6.0' then 'Windows vista or Server 2008' + when '6.1' then 'Windows 7 or Server 2008R2' + when '6.2' then 'Windows 8 or Server 2012' + when '6.3' then 'Windows 8.1 or Server 2012R2' + when '10.0' then 'Windows 10' +end +``` + +## Windows ChefSpec Matchers + +The Windows cookbook includes custom [ChefSpec](https://github.com/sethvargo/chefspec) matchers you can use to test your own cookbooks that consume Windows cookbook LWRPs. + +### Example Matcher Usage + +```ruby +expect(chef_run).to install_windows_package('Node.js').with( + source: 'http://nodejs.org/dist/v0.10.26/x64/node-v0.10.26-x64.msi') +``` + +### Windows Cookbook Matchers + +- create_windows_auto_run +- remove_windows_auto_run +- create_windows_certificate +- delete_windows_certificate +- add_acl_to_windows_certificate +- create_windows_certificate_binding +- delete_windows_certificate_binding +- install_windows_feature +- install_windows_feature_dism +- install_windows_feature_servermanagercmd +- install_windows_feature_powershell +- remove_windows_feature +- remove_windows_feature_dism +- remove_windows_feature_servermanagercmd +- remove_windows_feature_powershell +- delete_windows_feature +- delete_windows_feature_dism +- delete_windows_feature_powershell +- install_windows_font +- create_windows_http_acl +- delete_windows_http_acl +- install_windows_package +- remove_windows_package +- set_windows_pagefile +- add_windows_path +- remove_windows_path +- create_windows_printer +- delete_windows_printer +- create_windows_printer_port +- delete_windows_printer_port +- create_windows_shortcut +- create_windows_shortcut +- create_windows_task +- disable_windows_task +- enable_windows_task +- delete_windows_task +- run_windows_task +- change_windows_task +- unzip_windows_zipfile_to +- zip_windows_zipfile_to + +## Usage + +Place an explicit dependency on this cookbook (using depends in the cookbook's metadata.rb) from any cookbook where you would like to use the Windows-specific resources/providers that ship with this cookbook. + +```ruby +depends 'windows' +``` + +## License & Authors + +- Author:: Seth Chisamore ([schisamo@chef.io](mailto:schisamo@chef.io)) +- Author:: Doug MacEachern ([dougm@vmware.com](mailto:dougm@vmware.com)) +- Author:: Paul Morton ([pmorton@biaprotect.com](mailto:pmorton@biaprotect.com)) +- Author:: Doug Ireton ([doug.ireton@nordstrom.com](mailto:doug.ireton@nordstrom.com)) + +```text +Copyright 2011-2016, Chef Software, Inc. +Copyright 2010, VMware, Inc. +Copyright 2011, Business Intelligence Associates, Inc +Copyright 2012, Nordstrom, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +``` diff --git a/cookbooks/windows/attributes/default.rb b/cookbooks/windows/attributes/default.rb index 0d043c2..7e63845 100644 --- a/cookbooks/windows/attributes/default.rb +++ b/cookbooks/windows/attributes/default.rb @@ -1,24 +1,21 @@ -# -# Author:: Seth Chisamore () -# Cookbook Name:: windows -# Attribute:: default -# -# Copyright 2011-2015, Chef Software, Inc -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -default['windows']['allow_pending_reboots'] = true -default['windows']['allow_reboot_on_failure'] = false -default['windows']['rubyzipversion'] = nil -default['windows']['reboot_timeout'] = 60 +# +# Author:: Seth Chisamore () +# Cookbook:: windows +# Attribute:: default +# +# Copyright:: 2011-2017, Chef Software, Inc +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +default['windows']['rubyzipversion'] = nil diff --git a/cookbooks/windows/files/default/handlers/windows_reboot_handler.rb b/cookbooks/windows/files/default/handlers/windows_reboot_handler.rb deleted file mode 100644 index 874b751..0000000 --- a/cookbooks/windows/files/default/handlers/windows_reboot_handler.rb +++ /dev/null @@ -1,83 +0,0 @@ -# -# Author:: Seth Chisamore () -# Copyright:: Copyright (c) 2011 Chef Software, Inc -# License:: Apache License, Version 2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -class WindowsRebootHandler < Chef::Handler - include Chef::Mixin::ShellOut - - def initialize(allow_pending_reboots = true, timeout = 60, reason = 'Chef client run') - @allow_pending_reboots = allow_pending_reboots - @timeout = timeout - @reason = reason - end - - def report - log_message, reboot = begin - if reboot_requested? - ["chef_handler[#{self.class}] requested reboot will occur in #{timeout} seconds", true] - elsif reboot_pending? - if @allow_pending_reboots - ["chef_handler[#{self.class}] reboot pending - automatic reboot will occur in #{timeout} seconds", true] - else - ["chef_handler[#{self.class}] reboot pending but handler not configured to act on pending reboots - please reboot node manually", false] - end - else - ["chef_handler[#{self.class}] no reboot requested or pending", false] - end - end - - Chef::Log.warn(log_message) - shell_out!("shutdown /r /t #{timeout} /c \"#{reason}\"") if reboot - end - - private - - # reboot cause CHEF says so: - # reboot explicitly requested in our cookbook code - def reboot_requested? - node.run_state[:reboot_requested] == true - end - - if Chef::VERSION > '11.12' - include Chef::DSL::RebootPending - else - # reboot cause WIN says so: - # reboot pending because of some configuration action we performed - def reboot_pending? - # this key will only exit if the system need a reboot to update some file currently in use - # see http://technet.microsoft.com/en-us/library/cc960241.aspx - Registry.value_exists?('HKLM\SYSTEM\CurrentControlSet\Control\Session Manager', 'PendingFileRenameOperations') || - # 1 for any value means reboot pending - # "9306cdfc-c4a1-4a22-9996-848cb67eddc3"=1 - (Registry.key_exists?('HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired') && - Registry.get_values('HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired').select { |v| v[2] == 1 }.any?) || - # this key will only exit if the system is pending a reboot - ::Registry.key_exists?('HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending') || - # 1, 2 or 3 for 'Flags' value means reboot pending - (Registry.key_exists?('HKLM\SOFTWARE\Microsoft\Updates\UpdateExeVolatile') && - [1, 2, 3].include?(Registry.get_value('HKLM\SOFTWARE\Microsoft\Updates\UpdateExeVolatile', 'Flags'))) - end - end - - def timeout - node.run_state[:reboot_timeout] || node['windows']['reboot_timeout'] || @timeout - end - - def reason - node.run_state[:reboot_reason] || @reason - end -end diff --git a/cookbooks/windows/files/dism_features.rb b/cookbooks/windows/files/dism_features.rb new file mode 100644 index 0000000..804dcc0 --- /dev/null +++ b/cookbooks/windows/files/dism_features.rb @@ -0,0 +1,45 @@ +# +# Author:: Wade Peacock +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +# limitations under the License. +# + +Ohai.plugin(:DismFeatures) do + provides 'dism_features' + collect_data(:windows) do + dism_features Mash.new + # This is for 32-bit ruby/chef client on 64-bit Windows + # This emulates the locate_sysnative_cmd helper as it is not available + cmd = 'dism.exe' + dism = if ::File.exist?("#{ENV['WINDIR']}\\sysnative\\#{cmd}") + "#{ENV['WINDIR']}\\sysnative\\#{cmd}" + elsif ::File.exist?("#{ENV['WINDIR']}\\system32\\#{cmd}") + "#{ENV['WINDIR']}\\system32\\#{cmd}" + else + cmd + end + # Grab raw feature information from dism command line + raw_list_of_features = shell_out("#{dism} /Get-Features /Online /Format:Table").stdout + # Split stdout into an array by windows line ending + features_list = raw_list_of_features.split("\r\n") + features_list.each do |feature_details_raw| + # Skip lines that do not match Enable / Disable + next unless feature_details_raw =~ /(En|Dis)able/ + # Strip trailing whitespace characters then split on n number of spaces + | + n number of spaces + feature_details = feature_details_raw.strip.split(/\s+[|]\s+/) + # Add to Mash + dism_features[feature_details.first] = feature_details.last + end + end +end diff --git a/cookbooks/windows/libraries/feature_base.rb b/cookbooks/windows/libraries/feature_base.rb deleted file mode 100644 index 2ed8fb2..0000000 --- a/cookbooks/windows/libraries/feature_base.rb +++ /dev/null @@ -1,57 +0,0 @@ -class Chef - class Provider - class WindowsFeature - module Base - def action_install - unless installed? - install_feature(@new_resource.feature_name) - @new_resource.updated_by_last_action(true) - Chef::Log.info("#{@new_resource} installed feature") - else - Chef::Log.debug("#{@new_resource} is already installed - nothing to do") - end - end - - def action_remove - if installed? - remove_feature(@new_resource.feature_name) - @new_resource.updated_by_last_action(true) - Chef::Log.info("#{@new_resource} removed") - else - Chef::Log.debug("#{@new_resource} feature does not exist - nothing to do") - end - end - - def action_delete - if available? - delete_feature(@new_resource.feature_name) - @new_resource.updated_by_last_action(true) - Chef::Log.info("#{@new_resource} deleted") - else - Chef::Log.debug("#{@new_resource} feature is not installed - nothing to do") - end - end - - def install_feature(_name) - fail Chef::Exceptions::UnsupportedAction, "#{self} does not support :install" - end - - def remove_feature(_name) - fail Chef::Exceptions::UnsupportedAction, "#{self} does not support :remove" - end - - def delete_feature(_name) - fail Chef::Exceptions::UnsupportedAction, "#{self} does not support :delete" - end - - def installed? - fail Chef::Exceptions::Override, "You must override installed? in #{self}" - end - - def available? - fail Chef::Exceptions::Override, "You must override available? in #{self}" - end - end - end - end -end diff --git a/cookbooks/windows/libraries/matchers.rb b/cookbooks/windows/libraries/matchers.rb index b39b4fc..8299d94 100644 --- a/cookbooks/windows/libraries/matchers.rb +++ b/cookbooks/windows/libraries/matchers.rb @@ -1,452 +1,586 @@ -if defined?(ChefSpec) - chefspec_version = Gem.loaded_specs['chefspec'].version - if chefspec_version < Gem::Version.new('4.1.0') - define_method = ChefSpec::Runner.method(:define_runner_method) - else - define_method = ChefSpec.method(:define_matcher) - end - - define_method.call :windows_package - define_method.call :windows_feature - define_method.call :windows_task - define_method.call :windows_path - define_method.call :windows_batch - define_method.call :windows_pagefile - define_method.call :windows_zipfile - define_method.call :windows_shortcut - define_method.call :windows_auto_run - define_method.call :windows_printer - define_method.call :windows_printer_port - define_method.call :windows_reboot - # - # Assert that a +windows_package+ resource exists in the Chef run with the - # action +:install+. Given a Chef Recipe that installs "Node.js" as a - # +windows_package+: - # - # windows_package 'Node.js' do - # source 'http://nodejs.org/dist/v0.10.26/x64/node-v0.10.26-x64.msi' - # action :install - # end - # - # The Examples section demonstrates the different ways to test a - # +windows_package+ resource with ChefSpec. - # - # @example Assert that a +windows_package+ was installed - # expect(chef_run).to install_windows_package('Node.js') - # - # @example Assert that a +windows_package+ was _not_ installed - # expect(chef_run).to_not install_windows_package('7-zip') - # - # - # @param [String, Regex] resource_name - # the name of the resource to match - # - # @return [ChefSpec::Matchers::ResourceMatcher] - # - def install_windows_package(resource_name) - ChefSpec::Matchers::ResourceMatcher.new(:windows_package, :install, resource_name) - end - - # - # Assert that a +windows_package+ resource exists in the Chef run with the - # action +:remove+. Given a Chef Recipe that removes "Node.js" as a - # +windows_package+: - # - # windows_package 'Node.js' do - # action :remove - # end - # - # The Examples section demonstrates the different ways to test a - # +windows_package+ resource with ChefSpec. - # - # @example Assert that a +windows_package+ was installed - # expect(chef_run).to remove_windows_package('Node.js') - # - # @example Assert that a +windows_package+ was _not_ removed - # expect(chef_run).to_not remove_windows_package('7-zip') - # - # - # @param [String, Regex] resource_name - # the name of the resource to match - # - # @return [ChefSpec::Matchers::ResourceMatcher] - # - def remove_windows_package(resource_name) - ChefSpec::Matchers::ResourceMatcher.new(:windows_package, :remove, resource_name) - end - - # - # Assert that a +windows_feature+ resource exists in the Chef run with the - # action +:install+. Given a Chef Recipe that installs "NetFX3" as a - # +windows_feature+: - # - # windows_feature 'NetFX3' do - # action :install - # end - # - # The Examples section demonstrates the different ways to test a - # +windows_feature+ resource with ChefSpec. - # - # @example Assert that a +windows_feature+ was installed - # expect(chef_run).to install_windows_feature('NetFX3') - # - # @example Assert that a +windows_feature+ was _not_ installed - # expect(chef_run).to_not install_windows_feature('NetFX3') - # - # - # @param [String, Regex] resource_name - # the name of the resource to match - # - # @return [ChefSpec::Matchers::ResourceMatcher] - # - def install_windows_feature(resource_name) - ChefSpec::Matchers::ResourceMatcher.new(:windows_feature, :install, resource_name) - end - - # - # Assert that a +windows_feature+ resource exists in the Chef run with the - # action +:remove+. Given a Chef Recipe that removes "NetFX3" as a - # +windows_feature+: - # - # windows_feature 'NetFX3' do - # action :remove - # end - # - # The Examples section demonstrates the different ways to test a - # +windows_feature+ resource with ChefSpec. - # - # @example Assert that a +windows_feature+ was removed - # expect(chef_run).to remove_windows_feature('NetFX3') - # - # - # @param [String, Regex] resource_name - # the name of the resource to match - # - # @return [ChefSpec::Matchers::ResourceMatcher] - # - def remove_windows_feature(resource_name) - ChefSpec::Matchers::ResourceMatcher.new(:windows_feature, :remove, resource_name) - end - - # - # Assert that a +windows_feature+ resource exists in the Chef run with the - # action +:delete+. Given a Chef Recipe that deletes "NetFX3" as a - # +windows_feature+: - # - # windows_feature 'NetFX3' do - # action :delete - # end - # - # The Examples section demonstrates the different ways to test a - # +windows_feature+ resource with ChefSpec. - # - # @example Assert that a +windows_feature+ was deleted - # expect(chef_run).to delete_windows_feature('NetFX3') - # - # - # @param [String, Regex] resource_name - # the name of the resource to match - # - # @return [ChefSpec::Matchers::ResourceMatcher] - # - def delete_windows_feature(resource_name) - ChefSpec::Matchers::ResourceMatcher.new(:windows_feature, :delete, resource_name) - end - - # - # Assert that a +windows_task+ resource exists in the Chef run with the - # action +:create+. Given a Chef Recipe that creates "mytask" as a - # +windows_task+: - # - # windows_task 'mytask' do - # command 'mybatch.bat' - # action :create - # end - # - # The Examples section demonstrates the different ways to test a - # +windows_task+ resource with ChefSpec. - # - # @example Assert that a +windows_task+ was created - # expect(chef_run).to create_windows_task('mytask') - # - # - # @param [String, Regex] resource_name - # the name of the resource to match - # - # @return [ChefSpec::Matchers::ResourceMatcher] - # - def create_windows_task(resource_name) - ChefSpec::Matchers::ResourceMatcher.new(:windows_task, :create, resource_name) - end - - # - # Assert that a +windows_task+ resource exists in the Chef run with the - # action +:delete+. Given a Chef Recipe that deletes "mytask" as a - # +windows_task+: - # - # windows_task 'mytask' do - # action :delete - # end - # - # The Examples section demonstrates the different ways to test a - # +windows_task+ resource with ChefSpec. - # - # @example Assert that a +windows_task+ was deleted - # expect(chef_run).to delete_windows_task('mytask') - # - # - # @param [String, Regex] resource_name - # the name of the resource to match - # - # @return [ChefSpec::Matchers::ResourceMatcher] - # - def delete_windows_task(resource_name) - ChefSpec::Matchers::ResourceMatcher.new(:windows_task, :delete, resource_name) - end - - # - # Assert that a +windows_task+ resource exists in the Chef run with the - # action +:run+. Given a Chef Recipe that runs "mytask" as a - # +windows_task+: - # - # windows_task 'mytask' do - # action :run - # end - # - # The Examples section demonstrates the different ways to test a - # +windows_task+ resource with ChefSpec. - # - # @example Assert that a +windows_task+ was run - # expect(chef_run).to run_windows_task('mytask') - # - # - # @param [String, Regex] resource_name - # the name of the resource to match - # - # @return [ChefSpec::Matchers::ResourceMatcher] - # - def run_windows_task(resource_name) - ChefSpec::Matchers::ResourceMatcher.new(:windows_task, :run, resource_name) - end - - # - # Assert that a +windows_task+ resource exists in the Chef run with the - # action +:change+. Given a Chef Recipe that changes "mytask" as a - # +windows_task+: - # - # windows_task 'mytask' do - # action :change - # end - # - # The Examples section demonstrates the different ways to test a - # +windows_task+ resource with ChefSpec. - # - # @example Assert that a +windows_task+ was changed - # expect(chef_run).to change_windows_task('mytask') - # - # - # @param [String, Regex] resource_name - # the name of the resource to match - # - # @return [ChefSpec::Matchers::ResourceMatcher] - # - def change_windows_task(resource_name) - ChefSpec::Matchers::ResourceMatcher.new(:windows_task, :change, resource_name) - end - - # - # Assert that a +windows_path+ resource exists in the Chef run with the - # action +:add+. Given a Chef Recipe that adds "C:\7-Zip" to the Windows - # PATH env var - # - # windows_path 'C:\7-Zip' do - # action :add - # end - # - # The Examples section demonstrates the different ways to test a - # +windows_path+ resource with ChefSpec. - # - # @example Assert that a +windows_path+ was added - # expect(chef_run).to add_windows_path('C:\7-Zip') - # - # - # @param [String, Regex] resource_name - # the name of the resource to match - # - # @return [ChefSpec::Matchers::ResourceMatcher] - # - def add_windows_path(resource_name) - ChefSpec::Matchers::ResourceMatcher.new(:windows_path, :add, resource_name) - end - - # - # Assert that a +windows_path+ resource exists in the Chef run with the - # action +:remove+. Given a Chef Recipe that removes "C:\7-Zip" from the - # Windows PATH env var - # - # windows_path 'C:\7-Zip' do - # action :remove - # end - # - # The Examples section demonstrates the different ways to test a - # +windows_path+ resource with ChefSpec. - # - # @example Assert that a +windows_path+ was removed - # expect(chef_run).to remove_windows_path('C:\7-Zip') - # - # - # @param [String, Regex] resource_name - # the name of the resource to match - # - # @return [ChefSpec::Matchers::ResourceMatcher] - # - def remove_windows_path(resource_name) - ChefSpec::Matchers::ResourceMatcher.new(:windows_path, :remove, resource_name) - end - - # - # Assert that a +windows_batch+ resource exists in the Chef run with the - # action +:run+. Given a Chef Recipe that runs a batch script - # - # windows_batch "unzip_and_move_ruby" do - # code <<-EOH - # 7z.exe x #{Chef::Config[:file_cache_path]}/ruby-1.8.7-p352-i386-mingw32.7z - # -oC:\\source -r -y - # xcopy C:\\source\\ruby-1.8.7-p352-i386-mingw32 C:\\ruby /e /y - # EOH - # end - # - # The Examples section demonstrates the different ways to test a - # +windows_path+ resource with ChefSpec. - # - # @example Assert that a +windows_path+ was removed - # expect(chef_run).to run_windows_batch('unzip_and_move_ruby') - # - # - # @param [String, Regex] resource_name - # the name of the resource to match - # - # @return [ChefSpec::Matchers::ResourceMatcher] - # - def run_windows_batch(resource_name) - ChefSpec::Matchers::ResourceMatcher.new(:windows_batch, :run, resource_name) - end - - # - # Assert that a +windows_pagefile+ resource exists in the Chef run with the - # action +:set+. Given a Chef Recipe that sets a pagefile - # - # windows_pagefile "pagefile" do - # system_managed true - # initial_size 1024 - # maximum_size 4096 - # end - # - # The Examples section demonstrates the different ways to test a - # +windows_pagefile+ resource with ChefSpec. - # - # @example Assert that a +windows_pagefile+ was set - # expect(chef_run).to set_windows_pagefile('pagefile').with( - # initial_size: 1024) - # - # - # @param [String, Regex] resource_name - # the name of the resource to match - # - # @return [ChefSpec::Matchers::ResourceMatcher] - # - def set_windows_pagefile(resource_name) - ChefSpec::Matchers::ResourceMatcher.new(:windows_pagefile, :set, resource_name) - end - - # - # Assert that a +windows_zipfile+ resource exists in the Chef run with the - # action +:unzip+. Given a Chef Recipe that extracts "SysinternalsSuite.zip" - # to c:/bin - # - # windows_zipfile "c:/bin" do - # source "http://download.sysinternals.com/Files/SysinternalsSuite.zip" - # action :unzip - # not_if {::File.exists?("c:/bin/PsExec.exe")} - # end - # - # The Examples section demonstrates the different ways to test a - # +windows_zipfile+ resource with ChefSpec. - # - # @example Assert that a +windows_zipfile+ was unzipped - # expect(chef_run).to unzip_windows_zipfile_to('c:/bin') - # - # - # @param [String, Regex] resource_name - # the name of the resource to match - # - # @return [ChefSpec::Matchers::ResourceMatcher] - # - def unzip_windows_zipfile_to(resource_name) - ChefSpec::Matchers::ResourceMatcher.new(:windows_zipfile, :unzip, resource_name) - end - - # - # Assert that a +windows_zipfile+ resource exists in the Chef run with the - # action +:zip+. Given a Chef Recipe that zips "c:/src" - # to c:/code.zip - # - # windows_zipfile "c:/code.zip" do - # source "c:/src" - # action :zip - # end - # - # The Examples section demonstrates the different ways to test a - # +windows_zipfile+ resource with ChefSpec. - # - # @example Assert that a +windows_zipfile+ was zipped - # expect(chef_run).to zip_windows_zipfile_to('c:/code.zip') - # - # - # @param [String, Regex] resource_name - # the name of the resource to match - # - # @return [ChefSpec::Matchers::ResourceMatcher] - # - def zip_windows_zipfile_to(resource_name) - ChefSpec::Matchers::ResourceMatcher.new(:windows_zipfile, :zip, resource_name) - end - - # All the other less commonly used LWRPs - def create_windows_shortcut(resource_name) - ChefSpec::Matchers::ResourceMatcher.new(:windows_shortcut, :create, resource_name) - end - - def create_windows_auto_run(resource_name) - ChefSpec::Matchers::ResourceMatcher.new(:windows_auto_run, :create, resource_name) - end - - def remove_windows_auto_run(resource_name) - ChefSpec::Matchers::ResourceMatcher.new(:windows_auto_run, :remove, resource_name) - end - - def create_windows_printer(resource_name) - ChefSpec::Matchers::ResourceMatcher.new(:windows_printer, :create, resource_name) - end - - def delete_windows_printer(resource_name) - ChefSpec::Matchers::ResourceMatcher.new(:windows_printer, :delete, resource_name) - end - - def create_windows_printer_port(resource_name) - ChefSpec::Matchers::ResourceMatcher.new(:windows_printer_port, :create, resource_name) - end - - def delete_windows_printer_port(resource_name) - ChefSpec::Matchers::ResourceMatcher.new(:windows_printer_port, :delete, resource_name) - end - - def request_windows_reboot(resource_name) - ChefSpec::Matchers::ResourceMatcher.new(:windows_reboot, :request, resource_name) - end - - def cancel_windows_reboot(resource_name) - ChefSpec::Matchers::ResourceMatcher.new(:windows_reboot, :cancel, resource_name) - end - -end +if defined?(ChefSpec) + + ChefSpec.define_matcher :windows_auto_run + ChefSpec.define_matcher :windows_certificate + ChefSpec.define_matcher :windows_certificate_binding + ChefSpec.define_matcher :windows_feature + ChefSpec.define_matcher :windows_feature_dism + ChefSpec.define_matcher :windows_feature_servermanagercmd + ChefSpec.define_matcher :windows_feature_powershell + ChefSpec.define_matcher :windows_font + ChefSpec.define_matcher :windows_http_acl + ChefSpec.define_matcher :windows_pagefile + ChefSpec.define_matcher :windows_path + ChefSpec.define_matcher :windows_printer + ChefSpec.define_matcher :windows_printer_port + ChefSpec.define_matcher :windows_share + ChefSpec.define_matcher :windows_shortcut + ChefSpec.define_matcher :windows_task + ChefSpec.define_matcher :windows_zipfile + + # + # Assert that a +windows_certificate+ resource exists in the Chef run with the + # action +:create+. Given a Chef Recipe that creates 'c:\test\mycert.pfx' as a + # +windows_certificate+: + # + # windows_certificate 'c:\test\mycert.pfx' do + # action :create + # end + # + # The Examples section demonstrates the different ways to test a + # +windows_certificate+ resource with ChefSpec. + # + # @example Assert that a +windows_certificate+ was created + # expect(chef_run).to create_windows_certificate('c:\test\mycert.pfx') + # + # + # @param [String, Regex] resource_name + # the name of the resource to match + # + # @return [ChefSpec::Matchers::ResourceMatcher] + # + def create_windows_certificate(resource_name) + ChefSpec::Matchers::ResourceMatcher.new(:windows_certificate, :create, resource_name) + end + + # + # Assert that a +windows_certificate+ resource exists in the Chef run with the + # action +:delete+. Given a Chef Recipe that deletes "me.acme.com" as a + # +windows_certificate+: + # + # windows_certificate 'me.acme.com' do + # action :delete + # end + # + # The Examples section demonstrates the different ways to test a + # +windows_certificate+ resource with ChefSpec. + # + # @example Assert that a +windows_certificate+ was _not_ deleted + # expect(chef_run).to_not delete_windows_certificate('me.acme.com') + # + # + # @param [String, Regex] resource_name + # the name of the resource to match + # + # @return [ChefSpec::Matchers::ResourceMatcher] + # + def delete_windows_certificate(resource_name) + ChefSpec::Matchers::ResourceMatcher.new(:windows_certificate, :delete, resource_name) + end + + # + # Assert that a +windows_certificate+ resource exists in the Chef run with the + # action +:acl_add+. Given a Chef Recipe that adds a private key acl to "me.acme.com" as a + # +windows_certificate+: + # + # windows_certificate 'me.acme.com' do + # private_key_acl ['acme\fred', 'pc\jane'] + # action :acl_add + # end + # + # The Examples section demonstrates the different ways to test a + # +windows_certificate+ resource with ChefSpec. + # + # @example Assert that a +windows_certificate+ was _not_ removed + # expect(chef_run).to add_acl_to_windows_certificate('me.acme.com').with(private_key_acl: ['acme\fred', 'pc\jane']) + # + # + # @param [String, Regex] resource_name + # the name of the resource to match + # + # @return [ChefSpec::Matchers::ResourceMatcher] + # + def add_acl_to_windows_certificate(resource_name) + ChefSpec::Matchers::ResourceMatcher.new(:windows_certificate, :acl_add, resource_name) + end + + # + # Assert that a +windows_feature+ resource exists in the Chef run with the + # action +:install+. Given a Chef Recipe that installs "NetFX3" as a + # +windows_feature+: + # + # windows_feature 'NetFX3' do + # action :install + # end + # + # The Examples section demonstrates the different ways to test a + # +windows_feature+ resource with ChefSpec. + # + # @example Assert that a +windows_feature+ was installed + # expect(chef_run).to install_windows_feature('NetFX3') + # + # @example Assert that a +windows_feature+ was _not_ installed + # expect(chef_run).to_not install_windows_feature('NetFX3') + # + # + # @param [String, Regex] resource_name + # the name of the resource to match + # + # @return [ChefSpec::Matchers::ResourceMatcher] + # + def install_windows_feature(resource_name) + ChefSpec::Matchers::ResourceMatcher.new(:windows_feature, :install, resource_name) + end + + def install_windows_feature_servermanagercmd(resource_name) + ChefSpec::Matchers::ResourceMatcher.new(:windows_feature_servermanagercmd, :install, resource_name) + end + + def install_windows_feature_dism(resource_name) + ChefSpec::Matchers::ResourceMatcher.new(:windows_feature_dism, :install, resource_name) + end + + def install_windows_feature_powershell(resource_name) + ChefSpec::Matchers::ResourceMatcher.new(:windows_feature_powershell, :install, resource_name) + end + + # + # Assert that a +windows_feature+ resource exists in the Chef run with the + # action +:remove+. Given a Chef Recipe that removes "NetFX3" as a + # +windows_feature+: + # + # windows_feature 'NetFX3' do + # action :remove + # end + # + # The Examples section demonstrates the different ways to test a + # +windows_feature+ resource with ChefSpec. + # + # @example Assert that a +windows_feature+ was removed + # expect(chef_run).to remove_windows_feature('NetFX3') + # + # + # @param [String, Regex] resource_name + # the name of the resource to match + # + # @return [ChefSpec::Matchers::ResourceMatcher] + # + def remove_windows_feature(resource_name) + ChefSpec::Matchers::ResourceMatcher.new(:windows_feature, :remove, resource_name) + end + + def remove_windows_feature_servermanagercmd(resource_name) + ChefSpec::Matchers::ResourceMatcher.new(:windows_feature_servermanagercmd, :remove, resource_name) + end + + def remove_windows_feature_dism(resource_name) + ChefSpec::Matchers::ResourceMatcher.new(:windows_feature_dism, :remove, resource_name) + end + + def remove_windows_feature_powershell(resource_name) + ChefSpec::Matchers::ResourceMatcher.new(:windows_feature_powershell, :remove, resource_name) + end + + # + # Assert that a +windows_feature+ resource exists in the Chef run with the + # action +:delete+. Given a Chef Recipe that deletes "NetFX3" as a + # +windows_feature+: + # + # windows_feature 'NetFX3' do + # action :delete + # end + # + # The Examples section demonstrates the different ways to test a + # +windows_feature+ resource with ChefSpec. + # + # @example Assert that a +windows_feature+ was deleted + # expect(chef_run).to delete_windows_feature('NetFX3') + # + # + # @param [String, Regex] resource_name + # the name of the resource to match + # + # @return [ChefSpec::Matchers::ResourceMatcher] + # + def delete_windows_feature(resource_name) + ChefSpec::Matchers::ResourceMatcher.new(:windows_feature, :delete, resource_name) + end + + def delete_windows_feature_dism(resource_name) + ChefSpec::Matchers::ResourceMatcher.new(:windows_feature_dism, :delete, resource_name) + end + + def delete_windows_feature_powershell(resource_name) + ChefSpec::Matchers::ResourceMatcher.new(:windows_feature_powershell, :delete, resource_name) + end + + # + # Assert that a +windows_task+ resource exists in the Chef run with the + # action +:create+. Given a Chef Recipe that creates "mytask" as a + # +windows_task+: + # + # windows_task 'mytask' do + # command 'mybatch.bat' + # action :create + # end + # + # The Examples section demonstrates the different ways to test a + # +windows_task+ resource with ChefSpec. + # + # @example Assert that a +windows_task+ was created + # expect(chef_run).to create_windows_task('mytask') + # + # + # @param [String, Regex] resource_name + # the name of the resource to match + # + # @return [ChefSpec::Matchers::ResourceMatcher] + # + def create_windows_task(resource_name) + ChefSpec::Matchers::ResourceMatcher.new(:windows_task, :create, resource_name) + end + + # + # Assert that a +windows_task+ resource exists in the Chef run with the + # action +:disable+. Given a Chef Recipe that creates "mytask" as a + # +windows_task+: + # + # windows_task 'mytask' do + # action :disable + # end + # + # The Examples section demonstrates the different ways to test a + # +windows_task+ resource with ChefSpec. + # + # @example Assert that a +windows_task+ was disabled + # expect(chef_run).to disable_windows_task('mytask') + # + # + # @param [String, Regex] resource_name + # the name of the resource to match + # + # @return [ChefSpec::Matchers::ResourceMatcher] + # + def disable_windows_task(resource_name) + ChefSpec::Matchers::ResourceMatcher.new(:windows_task, :disable, resource_name) + end + + # + # Assert that a +windows_task+ resource exists in the Chef run with the + # action +:enable+. Given a Chef Recipe that creates "mytask" as a + # +windows_task+: + # + # windows_task 'mytask' do + # action :enable + # end + # + # The Examples section demonstrates the different ways to test a + # +windows_task+ resource with ChefSpec. + # + # @example Assert that a +windows_task+ was enabled + # expect(chef_run).to enable_windows_task('mytask') + # + # + # @param [String, Regex] resource_name + # the name of the resource to match + # + # @return [ChefSpec::Matchers::ResourceMatcher] + # + def enable_windows_task(resource_name) + ChefSpec::Matchers::ResourceMatcher.new(:windows_task, :enable, resource_name) + end + + # + # Assert that a +windows_task+ resource exists in the Chef run with the + # action +:delete+. Given a Chef Recipe that deletes "mytask" as a + # +windows_task+: + # + # windows_task 'mytask' do + # action :delete + # end + # + # The Examples section demonstrates the different ways to test a + # +windows_task+ resource with ChefSpec. + # + # @example Assert that a +windows_task+ was deleted + # expect(chef_run).to delete_windows_task('mytask') + # + # + # @param [String, Regex] resource_name + # the name of the resource to match + # + # @return [ChefSpec::Matchers::ResourceMatcher] + # + def delete_windows_task(resource_name) + ChefSpec::Matchers::ResourceMatcher.new(:windows_task, :delete, resource_name) + end + + # + # Assert that a +windows_task+ resource exists in the Chef run with the + # action +:run+. Given a Chef Recipe that runs "mytask" as a + # +windows_task+: + # + # windows_task 'mytask' do + # action :run + # end + # + # The Examples section demonstrates the different ways to test a + # +windows_task+ resource with ChefSpec. + # + # @example Assert that a +windows_task+ was run + # expect(chef_run).to run_windows_task('mytask') + # + # + # @param [String, Regex] resource_name + # the name of the resource to match + # + # @return [ChefSpec::Matchers::ResourceMatcher] + # + def run_windows_task(resource_name) + ChefSpec::Matchers::ResourceMatcher.new(:windows_task, :run, resource_name) + end + + # + # Assert that a +windows_task+ resource exists in the Chef run with the + # action +:change+. Given a Chef Recipe that changes "mytask" as a + # +windows_task+: + # + # windows_task 'mytask' do + # action :change + # end + # + # The Examples section demonstrates the different ways to test a + # +windows_task+ resource with ChefSpec. + # + # @example Assert that a +windows_task+ was changed + # expect(chef_run).to change_windows_task('mytask') + # + # + # @param [String, Regex] resource_name + # the name of the resource to match + # + # @return [ChefSpec::Matchers::ResourceMatcher] + # + def change_windows_task(resource_name) + ChefSpec::Matchers::ResourceMatcher.new(:windows_task, :change, resource_name) + end + + # + # Assert that a +windows_path+ resource exists in the Chef run with the + # action +:add+. Given a Chef Recipe that adds "C:\7-Zip" to the Windows + # PATH env var + # + # windows_path 'C:\7-Zip' do + # action :add + # end + # + # The Examples section demonstrates the different ways to test a + # +windows_path+ resource with ChefSpec. + # + # @example Assert that a +windows_path+ was added + # expect(chef_run).to add_windows_path('C:\7-Zip') + # + # + # @param [String, Regex] resource_name + # the name of the resource to match + # + # @return [ChefSpec::Matchers::ResourceMatcher] + # + def add_windows_path(resource_name) + ChefSpec::Matchers::ResourceMatcher.new(:windows_path, :add, resource_name) + end + + # + # Assert that a +windows_path+ resource exists in the Chef run with the + # action +:remove+. Given a Chef Recipe that removes "C:\7-Zip" from the + # Windows PATH env var + # + # windows_path 'C:\7-Zip' do + # action :remove + # end + # + # The Examples section demonstrates the different ways to test a + # +windows_path+ resource with ChefSpec. + # + # @example Assert that a +windows_path+ was removed + # expect(chef_run).to remove_windows_path('C:\7-Zip') + # + # + # @param [String, Regex] resource_name + # the name of the resource to match + # + # @return [ChefSpec::Matchers::ResourceMatcher] + # + def remove_windows_path(resource_name) + ChefSpec::Matchers::ResourceMatcher.new(:windows_path, :remove, resource_name) + end + + # + # Assert that a +windows_pagefile+ resource exists in the Chef run with the + # action +:set+. Given a Chef Recipe that sets a pagefile + # + # windows_pagefile "pagefile" do + # system_managed true + # initial_size 1024 + # maximum_size 4096 + # end + # + # The Examples section demonstrates the different ways to test a + # +windows_pagefile+ resource with ChefSpec. + # + # @example Assert that a +windows_pagefile+ was set + # expect(chef_run).to set_windows_pagefile('pagefile').with( + # initial_size: 1024) + # + # + # @param [String, Regex] resource_name + # the name of the resource to match + # + # @return [ChefSpec::Matchers::ResourceMatcher] + # + def set_windows_pagefile(resource_name) + ChefSpec::Matchers::ResourceMatcher.new(:windows_pagefile, :set, resource_name) + end + + # + # Assert that a +windows_zipfile+ resource exists in the Chef run with the + # action +:unzip+. Given a Chef Recipe that extracts "SysinternalsSuite.zip" + # to c:/bin + # + # windows_zipfile "c:/bin" do + # source "http://download.sysinternals.com/Files/SysinternalsSuite.zip" + # action :unzip + # not_if {::File.exists?("c:/bin/PsExec.exe")} + # end + # + # The Examples section demonstrates the different ways to test a + # +windows_zipfile+ resource with ChefSpec. + # + # @example Assert that a +windows_zipfile+ was unzipped + # expect(chef_run).to unzip_windows_zipfile_to('c:/bin') + # + # + # @param [String, Regex] resource_name + # the name of the resource to match + # + # @return [ChefSpec::Matchers::ResourceMatcher] + # + def unzip_windows_zipfile_to(resource_name) + ChefSpec::Matchers::ResourceMatcher.new(:windows_zipfile, :unzip, resource_name) + end + + # + # Assert that a +windows_zipfile+ resource exists in the Chef run with the + # action +:zip+. Given a Chef Recipe that zips "c:/src" + # to c:/code.zip + # + # windows_zipfile "c:/code.zip" do + # source "c:/src" + # action :zip + # end + # + # The Examples section demonstrates the different ways to test a + # +windows_zipfile+ resource with ChefSpec. + # + # @example Assert that a +windows_zipfile+ was zipped + # expect(chef_run).to zip_windows_zipfile_to('c:/code.zip') + # + # + # @param [String, Regex] resource_name + # the name of the resource to match + # + # @return [ChefSpec::Matchers::ResourceMatcher] + # + def zip_windows_zipfile_to(resource_name) + ChefSpec::Matchers::ResourceMatcher.new(:windows_zipfile, :zip, resource_name) + end + + # + # Assert that a +windows_share+ resource exists in the Chef run with the + # action +:create+. Given a Chef Recipe that shares "c:/src" + # as Src + # + # windows_share "Src" do + # path "c:/src" + # action :create + # end + # + # The Examples section demonstrates the different ways to test a + # +windows_share+ resource with ChefSpec. + # + # @example Assert that a +windows_share+ was created + # expect(chef_run).to create_windows_share('Src') + # + # + # @param [String, Regex] resource_name + # the name of the resource to match + # + # @return [ChefSpec::Matchers::ResourceMatcher] + # + def create_windows_share(resource_name) + ChefSpec::Matchers::ResourceMatcher.new(:windows_share, :create, resource_name) + end + + # + # Assert that a +windows_share+ resource exists in the Chef run with the + # action +:delete+. Given a Chef Recipe that deletes share "c:/src" + # + # windows_share "Src" do + # action :delete + # end + # + # The Examples section demonstrates the different ways to test a + # +windows_share+ resource with ChefSpec. + # + # @example Assert that a +windows_share+ was created + # expect(chef_run).to delete_windows_share('Src') + # + # + # @param [String, Regex] resource_name + # the name of the resource to match + # + # @return [ChefSpec::Matchers::ResourceMatcher] + # + def delete_windows_share(resource_name) + ChefSpec::Matchers::ResourceMatcher.new(:windows_share, :delete, resource_name) + end + + # All the other less commonly used LWRPs + def create_windows_shortcut(resource_name) + ChefSpec::Matchers::ResourceMatcher.new(:windows_shortcut, :create, resource_name) + end + + def create_windows_auto_run(resource_name) + ChefSpec::Matchers::ResourceMatcher.new(:windows_auto_run, :create, resource_name) + end + + def remove_windows_auto_run(resource_name) + ChefSpec::Matchers::ResourceMatcher.new(:windows_auto_run, :remove, resource_name) + end + + def create_windows_printer(resource_name) + ChefSpec::Matchers::ResourceMatcher.new(:windows_printer, :create, resource_name) + end + + def delete_windows_printer(resource_name) + ChefSpec::Matchers::ResourceMatcher.new(:windows_printer, :delete, resource_name) + end + + def create_windows_printer_port(resource_name) + ChefSpec::Matchers::ResourceMatcher.new(:windows_printer_port, :create, resource_name) + end + + def delete_windows_printer_port(resource_name) + ChefSpec::Matchers::ResourceMatcher.new(:windows_printer_port, :delete, resource_name) + end + + def install_windows_font(resource_name) + ChefSpec::Matchers::ResourceMatcher.new(:windows_font, :install, resource_name) + end + + def create_windows_certificate_binding(resource_name) + ChefSpec::Matchers::ResourceMatcher.new(:windows_certificate_binding, :create, resource_name) + end + + def delete_windows_certificate_binding(resource_name) + ChefSpec::Matchers::ResourceMatcher.new(:windows_certificate_binding, :delete, resource_name) + end + + def create_windows_http_acl(resource_name) + ChefSpec::Matchers::ResourceMatcher.new(:windows_http_acl, :create, resource_name) + end + + def delete_windows_http_acl(resource_name) + ChefSpec::Matchers::ResourceMatcher.new(:windows_http_acl, :delete, resource_name) + end +end diff --git a/cookbooks/windows/libraries/powershell_helper.rb b/cookbooks/windows/libraries/powershell_helper.rb index aba93a3..e9261b4 100644 --- a/cookbooks/windows/libraries/powershell_helper.rb +++ b/cookbooks/windows/libraries/powershell_helper.rb @@ -1,53 +1,53 @@ -# -# Author:: Seth Chisamore () -# Cookbook Name:: windows -# Library:: helper -# -# Copyright:: 2011-2015, Chef Software, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -require 'chef/mixin/shell_out' - -module Powershell - module Helper - include Chef::Mixin::ShellOut - - def powershell_installed? - !powershell_version.nil? - end - - def interpreter - # force 64-bit powershell from 32-bit ruby process - if ::File.exist?("#{ENV['WINDIR']}\\sysnative\\WindowsPowershell\\v1.0\\powershell.exe") - "#{ENV['WINDIR']}\\sysnative\\WindowsPowershell\\v1.0\\powershell.exe" - elsif ::File.exist?("#{ENV['WINDIR']}\\system32\\WindowsPowershell\\v1.0\\powershell.exe") - "#{ENV['WINDIR']}\\system32\\WindowsPowershell\\v1.0\\powershell.exe" - else - 'powershell.exe' - end - end - - def powershell_version - cmd = shell_out("#{interpreter} -InputFormat none -Command \"& echo $PSVersionTable.psversion.major\"") - if cmd.stdout.empty? # PowerShell 1.0 doesn't have a $PSVersionTable - 1 - else - Regexp.last_match(1).to_i if cmd.stdout =~ /^(\d+)/ - end - rescue Errno::ENOENT - nil - end - end -end +# +# Author:: Seth Chisamore () +# Cookbook:: windows +# Library:: helper +# +# Copyright:: 2011-2017, Chef Software, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require 'chef/mixin/shell_out' + +module Powershell + module Helper + include Chef::Mixin::ShellOut + + def powershell_installed? + !powershell_version.nil? + end + + def interpreter + # force 64-bit powershell from 32-bit ruby process + if ::File.exist?("#{ENV['WINDIR']}\\sysnative\\WindowsPowershell\\v1.0\\powershell.exe") + "#{ENV['WINDIR']}\\sysnative\\WindowsPowershell\\v1.0\\powershell.exe" + elsif ::File.exist?("#{ENV['WINDIR']}\\system32\\WindowsPowershell\\v1.0\\powershell.exe") + "#{ENV['WINDIR']}\\system32\\WindowsPowershell\\v1.0\\powershell.exe" + else + 'powershell.exe' + end + end + + def powershell_version + cmd = shell_out("#{interpreter} -InputFormat none -Command \"& echo $PSVersionTable.psversion.major\"") + if cmd.stdout.empty? # PowerShell 1.0 doesn't have a $PSVersionTable + 1 + else + Regexp.last_match(1).to_i if cmd.stdout =~ /^(\d+)/ + end + rescue Errno::ENOENT + nil + end + end +end diff --git a/cookbooks/windows/libraries/powershell_out.rb b/cookbooks/windows/libraries/powershell_out.rb deleted file mode 100644 index ffd5c9e..0000000 --- a/cookbooks/windows/libraries/powershell_out.rb +++ /dev/null @@ -1,92 +0,0 @@ - -# -# WARNING -# -# THIS CODE HAS BEEN MOVED TO CORE CHEF. DO NOT SUMBIT PULL REQUESTS AGAINST THIS -# CODE. IT WILL BE REMOVED IN THE FUTURE. -# - -unless defined? Chef::Mixin::PowershellOut - class Chef - module Mixin - module PowershellOut - include Chef::Mixin::ShellOut - - begin - include Chef::Mixin::WindowsArchitectureHelper - rescue - # nothing to do, as the include will happen when windows_architecture_helper.rb - # is loaded. This is for ease of removal of that library when either - # powershell_out is core chef or powershell cookbook depends upon version - # of chef that has Chef::Mixin::WindowsArchitectureHelper in core chef - end - - def powershell_out(*command_args) - Chef::Log.warn 'The powershell_out library in the windows cookbook is deprecated.' - Chef::Log.warn 'Please upgrade to Chef 12.4.0 or later where it is built-in to core chef.' - script = command_args.first - options = command_args.last.is_a?(Hash) ? command_args.last : nil - - run_command(script, options) - end - - def powershell_out!(*command_args) - cmd = powershell_out(*command_args) - cmd.error! - cmd - end - - private - - def run_command(script, options) - if options && options[:architecture] - architecture = options[:architecture] - options.delete(:architecture) - else - architecture = node_windows_architecture(node) - end - - disable_redirection = wow64_architecture_override_required?(node, architecture) - - if disable_redirection - original_redirection_state = disable_wow64_file_redirection(node) - end - - command = build_command(script) - - if options - cmd = shell_out(command, options) - else - cmd = shell_out(command) - end - - if disable_redirection - restore_wow64_file_redirection(node, original_redirection_state) - end - - cmd - end - - def build_command(script) - flags = [ - # Hides the copyright banner at startup. - '-NoLogo', - # Does not present an interactive prompt to the user. - '-NonInteractive', - # Does not load the Windows PowerShell profile. - '-NoProfile', - # always set the ExecutionPolicy flag - # see http://technet.microsoft.com/en-us/library/ee176961.aspx - '-ExecutionPolicy RemoteSigned', - # Powershell will hang if STDIN is redirected - # http://connect.microsoft.com/PowerShell/feedback/details/572313/powershell-exe-can-hang-if-stdin-is-redirected - '-InputFormat None' - ] - - command = "powershell.exe #{flags.join(' ')} -Command \"#{script}\"" - command - end - end - end - end -end diff --git a/cookbooks/windows/libraries/registry_helper.rb b/cookbooks/windows/libraries/registry_helper.rb index 531d4a2..91ae91a 100644 --- a/cookbooks/windows/libraries/registry_helper.rb +++ b/cookbooks/windows/libraries/registry_helper.rb @@ -1,355 +1,356 @@ -# -# Author:: Doug MacEachern () -# Author:: Seth Chisamore () -# Author:: Paul Morton () -# Cookbook Name:: windows -# Provider:: registry -# -# Copyright:: 2010, VMware, Inc. -# Copyright:: 2011-2015, Chef Software, Inc. -# Copyright:: 2011, Business Intelligence Associates, Inc -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -if RUBY_PLATFORM =~ /mswin|mingw32|windows/ - require 'win32/registry' - require_relative 'wmi_helper' -end - -module Windows - module RegistryHelper - @@native_registry_constant = ENV['PROCESSOR_ARCHITEW6432'] == 'AMD64' ? 0x0100 : 0x0200 - - def get_hive_name(path) - Chef::Log.debug('Resolving registry shortcuts to full names') - - reg_path = path.split('\\') - hive_name = reg_path.shift - - hkey = { - 'HKLM' => 'HKEY_LOCAL_MACHINE', - 'HKCU' => 'HKEY_CURRENT_USER', - 'HKU' => 'HKEY_USERS' - }[hive_name] || hive_name - - Chef::Log.debug("Hive resolved to #{hkey}") - hkey - end - - def get_hive(path) - Chef::Log.debug("Getting hive for #{path}") - reg_path = path.split('\\') - hive_name = reg_path.shift - - hkey = get_hive_name(path) - - hive = { - 'HKEY_LOCAL_MACHINE' => ::Win32::Registry::HKEY_LOCAL_MACHINE, - 'HKEY_USERS' => ::Win32::Registry::HKEY_USERS, - 'HKEY_CURRENT_USER' => ::Win32::Registry::HKEY_CURRENT_USER - }[hkey] - - unless hive - Chef::Application.fatal!("Unsupported registry hive '#{hive_name}'") - end - - Chef::Log.debug("Registry hive resolved to #{hkey}") - hive - end - - def unload_hive(path) - hive = get_hive(path) - if hive == ::Win32::Registry::HKEY_USERS - reg_path = path.split('\\') - priv = Chef::WindowsPrivileged.new - begin - priv.reg_unload_key(reg_path[1]) - rescue - end - end - end - - def set_value(mode, path, values, type = nil) - hive, reg_path, hive_name, root_key, hive_loaded = get_reg_path_info(path) - key_name = reg_path.join('\\') - - Chef::Log.debug("Creating #{path}") - - create_key(path) unless key_exists?(path, true) - - hive.send(mode, key_name, ::Win32::Registry::KEY_ALL_ACCESS | @@native_registry_constant) do |reg| - changed_something = false - values.each do |k, val| - key = k.to_s # wtf. avoid "can't modify frozen string" in win32/registry.rb - cur_val = nil - begin - cur_val = reg[key] - rescue - # subkey does not exist (ok) - end - - next unless cur_val != val - - Chef::Log.debug("setting #{key}=#{val}") - - type = :string if type.nil? - - reg_type = { - binary: ::Win32::Registry::REG_BINARY, - string: ::Win32::Registry::REG_SZ, - multi_string: ::Win32::Registry::REG_MULTI_SZ, - expand_string: ::Win32::Registry::REG_EXPAND_SZ, - dword: ::Win32::Registry::REG_DWORD, - dword_big_endian: ::Win32::Registry::REG_DWORD_BIG_ENDIAN, - qword: ::Win32::Registry::REG_QWORD - }[type] - - reg.write(key, reg_type, val) - - ensure_hive_unloaded(hive_loaded) - - changed_something = true - end - return changed_something - end - false - end - - def get_value(path, value) - hive, reg_path, hive_name, root_key, hive_loaded = get_reg_path_info(path) - key = reg_path.join('\\') - - hive.open(key, ::Win32::Registry::KEY_ALL_ACCESS | @@native_registry_constant) do |reg| - begin - return reg[value] - rescue - return nil - ensure - ensure_hive_unloaded(hive_loaded) - end - end - end - - def get_values(path) - hive, reg_path, hive_name, root_key, hive_loaded = get_reg_path_info(path) - key = reg_path.join('\\') - hive.open(key, ::Win32::Registry::KEY_ALL_ACCESS | @@native_registry_constant) do |reg| - values = [] - begin - reg.each_value do |name, type, data| - values << [name, type, data] - end - rescue - ensure - ensure_hive_unloaded(hive_loaded) - end - values - end - end - - def delete_value(path, values) - hive, reg_path, hive_name, root_key, hive_loaded = get_reg_path_info(path) - key = reg_path.join('\\') - Chef::Log.debug("Deleting values in #{path}") - hive.open(key, ::Win32::Registry::KEY_ALL_ACCESS | @@native_registry_constant) do |reg| - values.each_key do |key| - name = key.to_s - # Ensure delete operation is idempotent. - if value_exists?(path, key) - Chef::Log.debug("Deleting value #{name} in #{path}") - reg.delete_value(name) - else - Chef::Log.debug("Value #{name} in #{path} does not exist, skipping.") - end - end - end - end - - def create_key(path) - hive, reg_path, hive_name, root_key, hive_loaded = get_reg_path_info(path) - key = reg_path.join('\\') - Chef::Log.debug("Creating registry key #{path}") - hive.create(key) - end - - def value_exists?(path, value) - if key_exists?(path, true) - - hive, reg_path, hive_name, root_key, hive_loaded = get_reg_path_info(path) - key = reg_path.join('\\') - - Chef::Log.debug("Attempting to open #{key}") - Chef::Log.debug("Native Constant #{@@native_registry_constant}") - Chef::Log.debug("Hive #{hive}") - - hive.open(key, ::Win32::Registry::KEY_READ | @@native_registry_constant) do |reg| - begin - rtn_value = reg[value] - return true - rescue - return false - ensure - ensure_hive_unloaded(hive_loaded) - end - end - - end - false - end - - # TODO: Does not load user registry... - def key_exists?(path, load_hive = false) - if load_hive - hive, reg_path, hive_name, root_key, hive_loaded = get_reg_path_info(path) - key = reg_path.join('\\') - else - hive = get_hive(path) - reg_path = path.split('\\') - hive_name = reg_path.shift - root_key = reg_path[0] - key = reg_path.join('\\') - hive_loaded = false - end - - begin - hive.open(key, ::Win32::Registry::Constants::KEY_READ | @@native_registry_constant) - return true - rescue - return false - ensure - ensure_hive_unloaded(hive_loaded) - end - end - - def get_user_hive_location(sid) - reg_key = "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\#{sid}" - Chef::Log.debug("Looking for profile at #{reg_key}") - if key_exists?(reg_key) - return get_value(reg_key, 'ProfileImagePath') - else - return nil - end - end - - def resolve_user_to_sid(username) - user_query = execute_wmi_query("select * from Win32_UserAccount where Name='#{username}'") - sid = nil - - user_query.each do |user| - sid = wmi_object_property(user, 'sid') - break - end - - Chef::Log.debug("Resolved user SID to #{sid}") - return sid - rescue - return nil - end - - def hive_loaded?(path) - hive = get_hive(path) - reg_path = path.split('\\') - hive_name = reg_path.shift - user_hive = path[0] - - if user_hive?(hive) - return key_exists?("#{hive_name}\\#{user_hive}") - else - return true - end - end - - def user_hive?(hive) - if hive == ::Win32::Registry::HKEY_USERS - return true - else - return true - end - end - - def get_reg_path_info(path) - hive = get_hive(path) - reg_path = path.split('\\') - hive_name = reg_path.shift - root_key = reg_path[0] - hive_loaded = false - - if user_hive?(hive) && !key_exists?("#{hive_name}\\#{root_key}") - reg_path, hive_loaded = load_user_hive(hive, reg_path, root_key) - root_key = reg_path[0] - Chef::Log.debug("Resolved user (#{path}) to (#{reg_path.join('/')})") - end - - [hive, reg_path, hive_name, root_key, hive_loaded] - end - - def load_user_hive(hive, reg_path, user_hive) - Chef::Log.debug("Reg Path #{reg_path}") - # See if the hive is loaded. Logged in users will have a key that is named their SID - # if the user has specified the a path by SID and the user is logged in, this function - # should not be executed. - if user_hive?(hive) && !key_exists?("HKU\\#{user_hive}") - Chef::Log.debug('The user is not logged in and has not been specified by SID') - sid = resolve_user_to_sid(user_hive) - Chef::Log.debug("User SID resolved to (#{sid})") - # Now that the user has been resolved to a SID, check and see if the hive exists. - # If this exists by SID, the user is logged in and we should use that key. - # TODO: Replace the username with the sid and send it back because the username - # does not exist as the key location. - load_reg = false - if key_exists?("HKU\\#{sid}") - reg_path[0] = sid # use the active profile (user is logged on) - Chef::Log.debug("HKEY_USERS Mapped: #{user_hive} -> #{sid}") - else - Chef::Log.debug('User is not logged in') - load_reg = true - end - - # The user is not logged in, so we should load the registry from disk - if load_reg - profile_path = get_user_hive_location(sid) - unless profile_path.nil? - ntuser_dat = "#{profile_path}\\NTUSER.DAT" - if ::File.exist?(ntuser_dat) - priv = Chef::WindowsPrivileged.new - if priv.reg_load_key(sid, ntuser_dat) - Chef::Log.debug("RegLoadKey(#{sid}, #{user_hive}, #{ntuser_dat})") - reg_path[0] = sid - else - Chef::Log.debug("Failed RegLoadKey(#{sid}, #{user_hive}, #{ntuser_dat})") - end - end - end - end - end - - [reg_path, load_reg] - end - - private - - def ensure_hive_unloaded(hive_loaded = false) - if hive_loaded - Chef::Log.debug('Hive was loaded, we really should unload it') - unload_hive(path) - end - end - end -end - -module Registry - module_function - - extend Windows::RegistryHelper -end +# +# Author:: Doug MacEachern () +# Author:: Seth Chisamore () +# Author:: Paul Morton () +# Cookbook:: windows +# Provider:: registry +# +# Copyright:: 2010-2017, VMware, Inc. +# Copyright:: 2011-2017, Chef Software, Inc. +# Copyright:: 2011-2017, Business Intelligence Associates, Inc +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +if RUBY_PLATFORM =~ /mswin|mingw32|windows/ + require 'win32/registry' + require_relative 'wmi_helper' +end + +module Windows + module RegistryHelper + @@native_registry_constant = if ENV['PROCESSOR_ARCHITECTURE'] == 'AMD64' || + ENV['PROCESSOR_ARCHITEW6432'] == 'AMD64' + 0x0100 + else + 0x0200 + end + + def get_hive_name(path) + Chef::Log.debug('Resolving registry shortcuts to full names') + + reg_path = path.split('\\') + hive_name = reg_path.shift + + hkey = { + 'HKLM' => 'HKEY_LOCAL_MACHINE', + 'HKCU' => 'HKEY_CURRENT_USER', + 'HKU' => 'HKEY_USERS', + }[hive_name] || hive_name + + Chef::Log.debug("Hive resolved to #{hkey}") + hkey + end + + def get_hive(path) + Chef::Log.debug("Getting hive for #{path}") + reg_path = path.split('\\') + hive_name = reg_path.shift + + hkey = get_hive_name(path) + + hive = { + 'HKEY_LOCAL_MACHINE' => ::Win32::Registry::HKEY_LOCAL_MACHINE, + 'HKEY_USERS' => ::Win32::Registry::HKEY_USERS, + 'HKEY_CURRENT_USER' => ::Win32::Registry::HKEY_CURRENT_USER, + }[hkey] + + unless hive + Chef::Application.fatal!("Unsupported registry hive '#{hive_name}'") + end + + Chef::Log.debug("Registry hive resolved to #{hkey}") + hive + end + + def unload_hive(path) + hive = get_hive(path) + if hive == ::Win32::Registry::HKEY_USERS + reg_path = path.split('\\') + priv = Chef::WindowsPrivileged.new + begin + priv.reg_unload_key(reg_path[1]) + rescue + end + end + end + + def set_value(mode, path, values, type = nil) + hive, reg_path, hive_name, root_key, hive_loaded = get_reg_path_info(path) + key_name = reg_path.join('\\') + + Chef::Log.debug("Creating #{path}") + + create_key(path) unless key_exists?(path, true) + + hive.send(mode, key_name, ::Win32::Registry::KEY_ALL_ACCESS | @@native_registry_constant) do |reg| + changed_something = false + values.each do |k, val| + key = k.to_s # wtf. avoid "can't modify frozen string" in win32/registry.rb + cur_val = nil + begin + cur_val = reg[key] + rescue + # subkey does not exist (ok) + end + + next unless cur_val != val + + Chef::Log.debug("setting #{key}=#{val}") + + type = :string if type.nil? + + reg_type = { + binary: ::Win32::Registry::REG_BINARY, + string: ::Win32::Registry::REG_SZ, + multi_string: ::Win32::Registry::REG_MULTI_SZ, + expand_string: ::Win32::Registry::REG_EXPAND_SZ, + dword: ::Win32::Registry::REG_DWORD, + dword_big_endian: ::Win32::Registry::REG_DWORD_BIG_ENDIAN, + qword: ::Win32::Registry::REG_QWORD, + }[type] + + reg.write(key, reg_type, val) + + ensure_hive_unloaded(hive_loaded) + + changed_something = true + end + return changed_something + end + false + end + + def get_value(path, value) + hive, reg_path, hive_name, root_key, hive_loaded = get_reg_path_info(path) + key = reg_path.join('\\') + + hive.open(key, ::Win32::Registry::KEY_ALL_ACCESS | @@native_registry_constant) do |reg| + begin + return reg[value] + rescue + return nil + ensure + ensure_hive_unloaded(hive_loaded) + end + end + end + + def get_values(path) + hive, reg_path, hive_name, root_key, hive_loaded = get_reg_path_info(path) + key = reg_path.join('\\') + hive.open(key, ::Win32::Registry::KEY_ALL_ACCESS | @@native_registry_constant) do |reg| + values = [] + begin + reg.each_value do |name, type, data| + values << [name, type, data] + end + rescue + ensure + ensure_hive_unloaded(hive_loaded) + end + values + end + end + + def delete_value(path, values) + hive, reg_path, hive_name, root_key, hive_loaded = get_reg_path_info(path) + key = reg_path.join('\\') + Chef::Log.debug("Deleting values in #{path}") + hive.open(key, ::Win32::Registry::KEY_ALL_ACCESS | @@native_registry_constant) do |reg| + values.each_key do |key| + name = key.to_s + # Ensure delete operation is idempotent. + if value_exists?(path, key) + Chef::Log.debug("Deleting value #{name} in #{path}") + reg.delete_value(name) + else + Chef::Log.debug("Value #{name} in #{path} does not exist, skipping.") + end + end + end + end + + def create_key(path) + hive, reg_path, hive_name, root_key, hive_loaded = get_reg_path_info(path) + key = reg_path.join('\\') + Chef::Log.debug("Creating registry key #{path}") + hive.create(key) + end + + def value_exists?(path, value) + if key_exists?(path, true) + + hive, reg_path, hive_name, root_key, hive_loaded = get_reg_path_info(path) + key = reg_path.join('\\') + + Chef::Log.debug("Attempting to open #{key}") + Chef::Log.debug("Native Constant #{@@native_registry_constant}") + Chef::Log.debug("Hive #{hive}") + + hive.open(key, ::Win32::Registry::KEY_READ | @@native_registry_constant) do |reg| + begin + rtn_value = reg[value] + return true + rescue + return false + ensure + ensure_hive_unloaded(hive_loaded) + end + end + + end + false + end + + # TODO: Does not load user registry... + def key_exists?(path, load_hive = false) + if load_hive + hive, reg_path, hive_name, root_key, hive_loaded = get_reg_path_info(path) + key = reg_path.join('\\') + else + hive = get_hive(path) + reg_path = path.split('\\') + hive_name = reg_path.shift + root_key = reg_path[0] + key = reg_path.join('\\') + hive_loaded = false + end + + begin + hive.open(key, ::Win32::Registry::Constants::KEY_READ | @@native_registry_constant) + return true + rescue + return false + ensure + ensure_hive_unloaded(hive_loaded) + end + end + + def get_user_hive_location(sid) + reg_key = "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\#{sid}" + Chef::Log.debug("Looking for profile at #{reg_key}") + if key_exists?(reg_key) + return get_value(reg_key, 'ProfileImagePath') + else + return nil + end + end + + def resolve_user_to_sid(username) + user_query = execute_wmi_query("select * from Win32_UserAccount where Name='#{username}'") + sid = nil + + user_query.each do |user| + sid = wmi_object_property(user, 'sid') + break + end + + Chef::Log.debug("Resolved user SID to #{sid}") + return sid + rescue + return nil + end + + def hive_loaded?(path) + hive = get_hive(path) + reg_path = path.split('\\') + hive_name = reg_path.shift + user_hive = path[0] + + if user_hive?(hive) + return key_exists?("#{hive_name}\\#{user_hive}") + else + return true + end + end + + def user_hive?(hive) + hive == ::Win32::Registry::HKEY_USERS + end + + def get_reg_path_info(path) + hive = get_hive(path) + reg_path = path.split('\\') + hive_name = reg_path.shift + root_key = reg_path[0] + hive_loaded = false + + if user_hive?(hive) && !key_exists?("#{hive_name}\\#{root_key}") + reg_path, hive_loaded = load_user_hive(hive, reg_path, root_key) + root_key = reg_path[0] + Chef::Log.debug("Resolved user (#{path}) to (#{reg_path.join('/')})") + end + + [hive, reg_path, hive_name, root_key, hive_loaded] + end + + def load_user_hive(hive, reg_path, user_hive) + Chef::Log.debug("Reg Path #{reg_path}") + # See if the hive is loaded. Logged in users will have a key that is named their SID + # if the user has specified the a path by SID and the user is logged in, this function + # should not be executed. + if user_hive?(hive) && !key_exists?("HKU\\#{user_hive}") + Chef::Log.debug('The user is not logged in and has not been specified by SID') + sid = resolve_user_to_sid(user_hive) + Chef::Log.debug("User SID resolved to (#{sid})") + # Now that the user has been resolved to a SID, check and see if the hive exists. + # If this exists by SID, the user is logged in and we should use that key. + # TODO: Replace the username with the sid and send it back because the username + # does not exist as the key location. + load_reg = false + if key_exists?("HKU\\#{sid}") + reg_path[0] = sid # use the active profile (user is logged on) + Chef::Log.debug("HKEY_USERS Mapped: #{user_hive} -> #{sid}") + else + Chef::Log.debug('User is not logged in') + load_reg = true + end + + # The user is not logged in, so we should load the registry from disk + if load_reg + profile_path = get_user_hive_location(sid) + unless profile_path.nil? + ntuser_dat = "#{profile_path}\\NTUSER.DAT" + if ::File.exist?(ntuser_dat) + priv = Chef::WindowsPrivileged.new + if priv.reg_load_key(sid, ntuser_dat) + Chef::Log.debug("RegLoadKey(#{sid}, #{user_hive}, #{ntuser_dat})") + reg_path[0] = sid + else + Chef::Log.debug("Failed RegLoadKey(#{sid}, #{user_hive}, #{ntuser_dat})") + end + end + end + end + end + + [reg_path, load_reg] + end + + private + + def ensure_hive_unloaded(hive_loaded = false) + if hive_loaded + Chef::Log.debug('Hive was loaded, we really should unload it') + unload_hive(path) + end + end + end +end + +module Registry + module_function + + extend Windows::RegistryHelper +end diff --git a/cookbooks/windows/libraries/version.rb b/cookbooks/windows/libraries/version.rb index 685aca8..64f6230 100644 --- a/cookbooks/windows/libraries/version.rb +++ b/cookbooks/windows/libraries/version.rb @@ -1,207 +1,207 @@ -# -# Author:: Seth Chisamore () -# Cookbook Name:: windows -# Library:: version -# -# Copyright:: 2011-2015, Chef Software, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -if RUBY_PLATFORM =~ /mswin|mingw32|windows/ - require_relative 'wmi_helper' - require 'Win32API' -end - -module Windows - class Version - # http://msdn.microsoft.com/en-us/library/ms724833(v=vs.85).aspx - - # Suite Masks - # Microsoft BackOffice components are installed. - VER_SUITE_BACKOFFICE = 0x00000004 unless defined?(VER_SUITE_BACKOFFICE) - # Windows Server 2003, Web Edition is installed. - VER_SUITE_BLADE = 0x00000400 unless defined?(VER_SUITE_BLADE) - # Windows Server 2003, Compute Cluster Edition is installed. - VER_SUITE_COMPUTE_SERVER = 0x00004000 unless defined?(VER_SUITE_COMPUTE_SERVER) - # Windows Server 2008 Datacenter, Windows Server 2003, Datacenter Edition, or Windows 2000 Datacenter Server is installed. - VER_SUITE_DATACENTER = 0x00000080 unless defined?(VER_SUITE_DATACENTER) - # Windows Server 2008 Enterprise, Windows Server 2003, Enterprise Edition, or Windows 2000 Advanced Server is installed. Refer to the Remarks section for more information about this bit flag. - VER_SUITE_ENTERPRISE = 0x00000002 unless defined?(VER_SUITE_ENTERPRISE) - # Windows XP Embedded is installed. - VER_SUITE_EMBEDDEDNT = 0x00000040 unless defined?(VER_SUITE_EMBEDDEDNT) - # Windows Vista Home Premium, Windows Vista Home Basic, or Windows XP Home Edition is installed. - VER_SUITE_PERSONAL = 0x00000200 unless defined?(VER_SUITE_PERSONAL) - # Remote Desktop is supported, but only one interactive session is supported. This value is set unless the system is running in application server mode. - VER_SUITE_SINGLEUSERTS = 0x00000100 unless defined?(VER_SUITE_SINGLEUSERTS) - # Microsoft Small Business Server was once installed on the system, but may have been upgraded to another version of Windows. Refer to the Remarks section for more information about this bit flag. - VER_SUITE_SMALLBUSINESS = 0x00000001 unless defined?(VER_SUITE_SMALLBUSINESS) - # Microsoft Small Business Server is installed with the restrictive client license in force. Refer to the Remarks section for more information about this bit flag. - VER_SUITE_SMALLBUSINESS_RESTRICTED = 0x00000020 unless defined?(VER_SUITE_SMALLBUSINESS_RESTRICTED) - # Windows Storage Server 2003 R2 or Windows Storage Server 2003is installed. - VER_SUITE_STORAGE_SERVER = 0x00002000 unless defined?(VER_SUITE_STORAGE_SERVER) - # Terminal Services is installed. This value is always set. - # If VER_SUITE_TERMINAL is set but VER_SUITE_SINGLEUSERTS is not set, the system is running in application server mode. - VER_SUITE_TERMINAL = 0x00000010 unless defined?(VER_SUITE_TERMINAL) - # Windows Home Server is installed. - VER_SUITE_WH_SERVER = 0x00008000 unless defined?(VER_SUITE_WH_SERVER) - - # Product Type - # The system is a domain controller and the operating system is Windows Server 2012, Windows Server 2008 R2, Windows Server 2008, Windows Server 2003, or Windows 2000 Server. - VER_NT_DOMAIN_CONTROLLER = 0x0000002 unless defined?(VER_NT_DOMAIN_CONTROLLER) - # The operating system is Windows Server 2012, Windows Server 2008 R2, Windows Server 2008, Windows Server 2003, or Windows 2000 Server. - # Note that a server that is also a domain controller is reported as VER_NT_DOMAIN_CONTROLLER, not VER_NT_SERVER. - VER_NT_SERVER = 0x0000003 unless defined?(VER_NT_SERVER) - # The operating system is Windows 7, Windows Vista, Windows XP Professional, Windows XP Home Edition, or Windows 2000 Professional. - VER_NT_WORKSTATION = 0x0000001 unless defined?(VER_NT_WORKSTATION) - - # GetSystemMetrics - # The build number if the system is Windows Server 2003 R2; otherwise, 0. - SM_SERVERR2 = 89 unless defined?(SM_SERVERR2) - - # http://msdn.microsoft.com/en-us/library/ms724358(v=vs.85).aspx - SKU = { - 0x00000006 => { ms_const: 'PRODUCT_BUSINESS', name: 'Business' }, - 0x00000010 => { ms_const: 'PRODUCT_BUSINESS_N', name: 'Business N' }, - 0x00000012 => { ms_const: 'PRODUCT_CLUSTER_SERVER', name: 'HPC Edition' }, - 0x00000008 => { ms_const: 'PRODUCT_DATACENTER_SERVER', name: 'Server Datacenter (full installation)' }, - 0x0000000C => { ms_const: 'PRODUCT_DATACENTER_SERVER_CORE', name: 'Server Datacenter (core installation)' }, - 0x00000027 => { ms_const: 'PRODUCT_DATACENTER_SERVER_CORE_V', name: 'Server Datacenter without Hyper-V (core installation)' }, - 0x00000025 => { ms_const: 'PRODUCT_DATACENTER_SERVER_V', name: 'Server Datacenter without Hyper-V (full installation)' }, - 0x00000004 => { ms_const: 'PRODUCT_ENTERPRISE', name: 'Enterprise' }, - 0x00000046 => { ms_const: 'PRODUCT_ENTERPRISE_E', name: 'Not supported' }, - 0x0000001B => { ms_const: 'PRODUCT_ENTERPRISE_N', name: 'Enterprise N' }, - 0x0000000A => { ms_const: 'PRODUCT_ENTERPRISE_SERVER', name: 'Server Enterprise (full installation)' }, - 0x0000000E => { ms_const: 'PRODUCT_ENTERPRISE_SERVER_CORE', name: 'Server Enterprise (core installation)' }, - 0x00000029 => { ms_const: 'PRODUCT_ENTERPRISE_SERVER_CORE_V', name: 'Server Enterprise without Hyper-V (core installation)' }, - 0x0000000F => { ms_const: 'PRODUCT_ENTERPRISE_SERVER_IA64', name: 'Server Enterprise for Itanium-based Systems' }, - 0x00000026 => { ms_const: 'PRODUCT_ENTERPRISE_SERVER_V', name: 'Server Enterprise without Hyper-V (full installation)' }, - 0x00000002 => { ms_const: 'PRODUCT_HOME_BASIC', name: 'Home Basic' }, - 0x00000043 => { ms_const: 'PRODUCT_HOME_BASIC_E', name: 'Not supported' }, - 0x00000005 => { ms_const: 'PRODUCT_HOME_BASIC_N', name: 'Home Basic N' }, - 0x00000003 => { ms_const: 'PRODUCT_HOME_PREMIUM', name: 'Home Premium' }, - 0x00000044 => { ms_const: 'PRODUCT_HOME_PREMIUM_E', name: 'Not supported' }, - 0x0000001A => { ms_const: 'PRODUCT_HOME_PREMIUM_N', name: 'Home Premium N' }, - 0x0000002A => { ms_const: 'PRODUCT_HYPERV', name: 'Microsoft Hyper-V Server' }, - 0x0000001E => { ms_const: 'PRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT', name: 'Windows Essential Business Server Management Server' }, - 0x00000020 => { ms_const: 'PRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING', name: 'Windows Essential Business Server Messaging Server' }, - 0x0000001F => { ms_const: 'PRODUCT_MEDIUMBUSINESS_SERVER_SECURITY', name: 'Windows Essential Business Server Security Server' }, - 0x00000030 => { ms_const: 'PRODUCT_PROFESSIONAL', name: 'Professional' }, - 0x00000045 => { ms_const: 'PRODUCT_PROFESSIONAL_E', name: 'Not supported' }, - 0x00000031 => { ms_const: 'PRODUCT_PROFESSIONAL_N', name: 'Professional N' }, - 0x00000067 => { ms_const: 'PRODUCT_PROFESSIONAL_WMC', name: 'Professional with Media Center' }, - 0x00000018 => { ms_const: 'PRODUCT_SERVER_FOR_SMALLBUSINESS', name: 'Windows Server 2008 for Windows Essential Server Solutions' }, - 0x00000023 => { ms_const: 'PRODUCT_SERVER_FOR_SMALLBUSINESS_V', name: 'Windows Server 2008 without Hyper-V for Windows Essential Server Solutions' }, - 0x00000021 => { ms_const: 'PRODUCT_SERVER_FOUNDATION', name: 'Server Foundation' }, - 0x00000022 => { ms_const: 'PRODUCT_HOME_PREMIUM_SERVER', name: 'Windows Home Server 2011' }, - 0x00000032 => { ms_const: 'PRODUCT_SB_SOLUTION_SERVER', name: 'Windows Small Business Server 2011 Essentials' }, - 0x00000013 => { ms_const: 'PRODUCT_HOME_SERVER', name: 'Windows Storage Server 2008 R2 Essentials' }, - 0x00000009 => { ms_const: 'PRODUCT_SMALLBUSINESS_SERVER', name: 'Windows Small Business Server' }, - 0x00000038 => { ms_const: 'PRODUCT_SOLUTION_EMBEDDEDSERVER', name: 'Windows MultiPoint Server' }, - 0x00000007 => { ms_const: 'PRODUCT_STANDARD_SERVER', name: 'Server Standard (full installation)' }, - 0x0000000D => { ms_const: 'PRODUCT_STANDARD_SERVER_CORE', name: 'Server Standard (core installation)' }, - 0x00000028 => { ms_const: 'PRODUCT_STANDARD_SERVER_CORE_V', name: 'Server Standard without Hyper-V (core installation)' }, - 0x00000024 => { ms_const: 'PRODUCT_STANDARD_SERVER_V', name: 'Server Standard without Hyper-V (full installation)' }, - 0x0000000B => { ms_const: 'PRODUCT_STARTER', name: 'Starter' }, - 0x00000042 => { ms_const: 'PRODUCT_STARTER_E', name: 'Not supported' }, - 0x0000002F => { ms_const: 'PRODUCT_STARTER_N', name: 'Starter N' }, - 0x00000017 => { ms_const: 'PRODUCT_STORAGE_ENTERPRISE_SERVER', name: 'Storage Server Enterprise' }, - 0x00000014 => { ms_const: 'PRODUCT_STORAGE_EXPRESS_SERVER', name: 'Storage Server Express' }, - 0x00000015 => { ms_const: 'PRODUCT_STORAGE_STANDARD_SERVER', name: 'Storage Server Standard' }, - 0x00000016 => { ms_const: 'PRODUCT_STORAGE_WORKGROUP_SERVER', name: 'Storage Server Workgroup' }, - 0x00000000 => { ms_const: 'PRODUCT_UNDEFINED', name: 'An unknown product' }, - 0x00000001 => { ms_const: 'PRODUCT_ULTIMATE', name: 'Ultimate' }, - 0x00000047 => { ms_const: 'PRODUCT_ULTIMATE_E', name: 'Not supported' }, - 0x0000001C => { ms_const: 'PRODUCT_ULTIMATE_N', name: 'Ultimate N' }, - 0x00000011 => { ms_const: 'PRODUCT_WEB_SERVER', name: 'Web Server (full installation)' }, - 0x0000001D => { ms_const: 'PRODUCT_WEB_SERVER_CORE', name: 'Web Server (core installation)' } - }.freeze unless defined?(SKU) - - attr_reader :major_version, :minor_version, :build_number, :service_pack_major_version, :service_pack_minor_version - attr_reader :version, :product_type, :product_suite, :sku - - def initialize - unless RUBY_PLATFORM =~ /mswin|mingw32|windows/ - fail NotImplementedError, 'only valid on Windows platform' - end - @version, @product_type, @product_suite, @sku, @service_pack_major_version, @service_pack_minor_version = get_os_info - @major_version, @minor_version, @build_number = version.split('.').map(&:to_i) - end - - WIN_VERSIONS = { - 'Windows Server 2012 R2' => { major: 6, minor: 3, callable: -> { @product_type != VER_NT_WORKSTATION } }, - 'Windows 8' => { major: 6, minor: 2, callable: -> { @product_type == VER_NT_WORKSTATION } }, - 'Windows Server 2012' => { major: 6, minor: 2, callable: -> { @product_type != VER_NT_WORKSTATION } }, - 'Windows 7' => { major: 6, minor: 1, callable: -> { @product_type == VER_NT_WORKSTATION } }, - 'Windows Server 2008 R2' => { major: 6, minor: 1, callable: -> { @product_type != VER_NT_WORKSTATION } }, - 'Windows Server 2008' => { major: 6, minor: 0, callable: -> { @product_type != VER_NT_WORKSTATION } }, - 'Windows Vista' => { major: 6, minor: 0, callable: -> { @product_type == VER_NT_WORKSTATION } }, - 'Windows Server 2003 R2' => { major: 5, minor: 2, callable: -> { Win32API.new('user32', 'GetSystemMetrics', 'I', 'I').call(SM_SERVERR2) != 0 } }, - 'Windows Home Server' => { major: 5, minor: 2, callable: -> { (@product_suite & VER_SUITE_WH_SERVER) == VER_SUITE_WH_SERVER } }, - 'Windows Server 2003' => { major: 5, minor: 2, callable: -> { Win32API.new('user32', 'GetSystemMetrics', 'I', 'I').call(SM_SERVERR2) == 0 } }, - 'Windows XP' => { major: 5, minor: 1 }, - 'Windows 2000' => { major: 5, minor: 0 } - }.freeze unless defined?(WIN_VERSIONS) - - marketing_names = [] - - # General Windows checks - WIN_VERSIONS.each do |k, v| - method_name = "#{k.gsub(/\s/, '_').downcase}?" - define_method(method_name) do - (@major_version == v[:major]) && - (@minor_version == v[:minor]) && - (v[:callable] ? v[:callable].call : true) - end - marketing_names << [k, method_name] - end - - define_method(:marketing_name) do - marketing_names.each do |mn| - break mn[0] if send(mn[1]) - end - end - - # Server Type checks - %w( core full datacenter ).each do |m| - define_method("server_#{m}?") do - if @sku - !(SKU[@sku][:name] =~ /#{m}/i).nil? - else - false - end - end - end - - private - - # Win32API call to GetSystemMetrics(SM_SERVERR2) - # returns: The build number if the system is Windows Server 2003 R2; otherwise, 0. - def sm_serverr2 - @sm_serverr2 ||= Win32API.new('user32', 'GetSystemMetrics', 'I', 'I').call(SM_SERVERR2) - end - - # query WMI Win32_OperatingSystem for required OS info - def get_os_info - cols = %w( Version ProductType OSProductSuite OperatingSystemSKU ServicePackMajorVersion ServicePackMinorVersion ) - os_info = execute_wmi_query('select * from Win32_OperatingSystem').each.next - cols.map do |c| - begin - wmi_object_property(os_info, c) - rescue # OperatingSystemSKU doesn't exist in all versions of Windows - nil - end - end - end - end -end +# +# Author:: Seth Chisamore () +# Cookbook:: windows +# Library:: version +# +# Copyright:: 2011-2017, Chef Software, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +if RUBY_PLATFORM =~ /mswin|mingw32|windows/ + require_relative 'wmi_helper' + require 'Win32API' +end + +module Windows + class Version + # http://msdn.microsoft.com/en-us/library/ms724833(v=vs.85).aspx + + # Suite Masks + # Microsoft BackOffice components are installed. + VER_SUITE_BACKOFFICE = 0x00000004 unless defined?(VER_SUITE_BACKOFFICE) + # Windows Server 2003, Web Edition is installed. + VER_SUITE_BLADE = 0x00000400 unless defined?(VER_SUITE_BLADE) + # Windows Server 2003, Compute Cluster Edition is installed. + VER_SUITE_COMPUTE_SERVER = 0x00004000 unless defined?(VER_SUITE_COMPUTE_SERVER) + # Windows Server 2008 Datacenter, Windows Server 2003, Datacenter Edition, or Windows 2000 Datacenter Server is installed. + VER_SUITE_DATACENTER = 0x00000080 unless defined?(VER_SUITE_DATACENTER) + # Windows Server 2008 Enterprise, Windows Server 2003, Enterprise Edition, or Windows 2000 Advanced Server is installed. Refer to the Remarks section for more information about this bit flag. + VER_SUITE_ENTERPRISE = 0x00000002 unless defined?(VER_SUITE_ENTERPRISE) + # Windows XP Embedded is installed. + VER_SUITE_EMBEDDEDNT = 0x00000040 unless defined?(VER_SUITE_EMBEDDEDNT) + # Windows Vista Home Premium, Windows Vista Home Basic, or Windows XP Home Edition is installed. + VER_SUITE_PERSONAL = 0x00000200 unless defined?(VER_SUITE_PERSONAL) + # Remote Desktop is supported, but only one interactive session is supported. This value is set unless the system is running in application server mode. + VER_SUITE_SINGLEUSERTS = 0x00000100 unless defined?(VER_SUITE_SINGLEUSERTS) + # Microsoft Small Business Server was once installed on the system, but may have been upgraded to another version of Windows. Refer to the Remarks section for more information about this bit flag. + VER_SUITE_SMALLBUSINESS = 0x00000001 unless defined?(VER_SUITE_SMALLBUSINESS) + # Microsoft Small Business Server is installed with the restrictive client license in force. Refer to the Remarks section for more information about this bit flag. + VER_SUITE_SMALLBUSINESS_RESTRICTED = 0x00000020 unless defined?(VER_SUITE_SMALLBUSINESS_RESTRICTED) + # Windows Storage Server 2003 R2 or Windows Storage Server 2003is installed. + VER_SUITE_STORAGE_SERVER = 0x00002000 unless defined?(VER_SUITE_STORAGE_SERVER) + # Terminal Services is installed. This value is always set. + # If VER_SUITE_TERMINAL is set but VER_SUITE_SINGLEUSERTS is not set, the system is running in application server mode. + VER_SUITE_TERMINAL = 0x00000010 unless defined?(VER_SUITE_TERMINAL) + # Windows Home Server is installed. + VER_SUITE_WH_SERVER = 0x00008000 unless defined?(VER_SUITE_WH_SERVER) + + # Product Type + # The system is a domain controller and the operating system is Windows Server 2012, Windows Server 2008 R2, Windows Server 2008, Windows Server 2003, or Windows 2000 Server. + VER_NT_DOMAIN_CONTROLLER = 0x0000002 unless defined?(VER_NT_DOMAIN_CONTROLLER) + # The operating system is Windows Server 2012, Windows Server 2008 R2, Windows Server 2008, Windows Server 2003, or Windows 2000 Server. + # Note that a server that is also a domain controller is reported as VER_NT_DOMAIN_CONTROLLER, not VER_NT_SERVER. + VER_NT_SERVER = 0x0000003 unless defined?(VER_NT_SERVER) + # The operating system is Windows 7, Windows Vista, Windows XP Professional, Windows XP Home Edition, or Windows 2000 Professional. + VER_NT_WORKSTATION = 0x0000001 unless defined?(VER_NT_WORKSTATION) + + # GetSystemMetrics + # The build number if the system is Windows Server 2003 R2; otherwise, 0. + SM_SERVERR2 = 89 unless defined?(SM_SERVERR2) + + # http://msdn.microsoft.com/en-us/library/ms724358(v=vs.85).aspx + SKU = { + 0x00000006 => { ms_const: 'PRODUCT_BUSINESS', name: 'Business' }, + 0x00000010 => { ms_const: 'PRODUCT_BUSINESS_N', name: 'Business N' }, + 0x00000012 => { ms_const: 'PRODUCT_CLUSTER_SERVER', name: 'HPC Edition' }, + 0x00000008 => { ms_const: 'PRODUCT_DATACENTER_SERVER', name: 'Server Datacenter (full installation)' }, + 0x0000000C => { ms_const: 'PRODUCT_DATACENTER_SERVER_CORE', name: 'Server Datacenter (core installation)' }, + 0x00000027 => { ms_const: 'PRODUCT_DATACENTER_SERVER_CORE_V', name: 'Server Datacenter without Hyper-V (core installation)' }, + 0x00000025 => { ms_const: 'PRODUCT_DATACENTER_SERVER_V', name: 'Server Datacenter without Hyper-V (full installation)' }, + 0x00000004 => { ms_const: 'PRODUCT_ENTERPRISE', name: 'Enterprise' }, + 0x00000046 => { ms_const: 'PRODUCT_ENTERPRISE_E', name: 'Not supported' }, + 0x0000001B => { ms_const: 'PRODUCT_ENTERPRISE_N', name: 'Enterprise N' }, + 0x0000000A => { ms_const: 'PRODUCT_ENTERPRISE_SERVER', name: 'Server Enterprise (full installation)' }, + 0x0000000E => { ms_const: 'PRODUCT_ENTERPRISE_SERVER_CORE', name: 'Server Enterprise (core installation)' }, + 0x00000029 => { ms_const: 'PRODUCT_ENTERPRISE_SERVER_CORE_V', name: 'Server Enterprise without Hyper-V (core installation)' }, + 0x0000000F => { ms_const: 'PRODUCT_ENTERPRISE_SERVER_IA64', name: 'Server Enterprise for Itanium-based Systems' }, + 0x00000026 => { ms_const: 'PRODUCT_ENTERPRISE_SERVER_V', name: 'Server Enterprise without Hyper-V (full installation)' }, + 0x00000002 => { ms_const: 'PRODUCT_HOME_BASIC', name: 'Home Basic' }, + 0x00000043 => { ms_const: 'PRODUCT_HOME_BASIC_E', name: 'Not supported' }, + 0x00000005 => { ms_const: 'PRODUCT_HOME_BASIC_N', name: 'Home Basic N' }, + 0x00000003 => { ms_const: 'PRODUCT_HOME_PREMIUM', name: 'Home Premium' }, + 0x00000044 => { ms_const: 'PRODUCT_HOME_PREMIUM_E', name: 'Not supported' }, + 0x0000001A => { ms_const: 'PRODUCT_HOME_PREMIUM_N', name: 'Home Premium N' }, + 0x0000002A => { ms_const: 'PRODUCT_HYPERV', name: 'Microsoft Hyper-V Server' }, + 0x0000001E => { ms_const: 'PRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT', name: 'Windows Essential Business Server Management Server' }, + 0x00000020 => { ms_const: 'PRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING', name: 'Windows Essential Business Server Messaging Server' }, + 0x0000001F => { ms_const: 'PRODUCT_MEDIUMBUSINESS_SERVER_SECURITY', name: 'Windows Essential Business Server Security Server' }, + 0x00000030 => { ms_const: 'PRODUCT_PROFESSIONAL', name: 'Professional' }, + 0x00000045 => { ms_const: 'PRODUCT_PROFESSIONAL_E', name: 'Not supported' }, + 0x00000031 => { ms_const: 'PRODUCT_PROFESSIONAL_N', name: 'Professional N' }, + 0x00000067 => { ms_const: 'PRODUCT_PROFESSIONAL_WMC', name: 'Professional with Media Center' }, + 0x00000018 => { ms_const: 'PRODUCT_SERVER_FOR_SMALLBUSINESS', name: 'Windows Server 2008 for Windows Essential Server Solutions' }, + 0x00000023 => { ms_const: 'PRODUCT_SERVER_FOR_SMALLBUSINESS_V', name: 'Windows Server 2008 without Hyper-V for Windows Essential Server Solutions' }, + 0x00000021 => { ms_const: 'PRODUCT_SERVER_FOUNDATION', name: 'Server Foundation' }, + 0x00000022 => { ms_const: 'PRODUCT_HOME_PREMIUM_SERVER', name: 'Windows Home Server 2011' }, + 0x00000032 => { ms_const: 'PRODUCT_SB_SOLUTION_SERVER', name: 'Windows Small Business Server 2011 Essentials' }, + 0x00000013 => { ms_const: 'PRODUCT_HOME_SERVER', name: 'Windows Storage Server 2008 R2 Essentials' }, + 0x00000009 => { ms_const: 'PRODUCT_SMALLBUSINESS_SERVER', name: 'Windows Small Business Server' }, + 0x00000038 => { ms_const: 'PRODUCT_SOLUTION_EMBEDDEDSERVER', name: 'Windows MultiPoint Server' }, + 0x00000007 => { ms_const: 'PRODUCT_STANDARD_SERVER', name: 'Server Standard (full installation)' }, + 0x0000000D => { ms_const: 'PRODUCT_STANDARD_SERVER_CORE', name: 'Server Standard (core installation)' }, + 0x00000028 => { ms_const: 'PRODUCT_STANDARD_SERVER_CORE_V', name: 'Server Standard without Hyper-V (core installation)' }, + 0x00000024 => { ms_const: 'PRODUCT_STANDARD_SERVER_V', name: 'Server Standard without Hyper-V (full installation)' }, + 0x0000000B => { ms_const: 'PRODUCT_STARTER', name: 'Starter' }, + 0x00000042 => { ms_const: 'PRODUCT_STARTER_E', name: 'Not supported' }, + 0x0000002F => { ms_const: 'PRODUCT_STARTER_N', name: 'Starter N' }, + 0x00000017 => { ms_const: 'PRODUCT_STORAGE_ENTERPRISE_SERVER', name: 'Storage Server Enterprise' }, + 0x00000014 => { ms_const: 'PRODUCT_STORAGE_EXPRESS_SERVER', name: 'Storage Server Express' }, + 0x00000015 => { ms_const: 'PRODUCT_STORAGE_STANDARD_SERVER', name: 'Storage Server Standard' }, + 0x00000016 => { ms_const: 'PRODUCT_STORAGE_WORKGROUP_SERVER', name: 'Storage Server Workgroup' }, + 0x00000000 => { ms_const: 'PRODUCT_UNDEFINED', name: 'An unknown product' }, + 0x00000001 => { ms_const: 'PRODUCT_ULTIMATE', name: 'Ultimate' }, + 0x00000047 => { ms_const: 'PRODUCT_ULTIMATE_E', name: 'Not supported' }, + 0x0000001C => { ms_const: 'PRODUCT_ULTIMATE_N', name: 'Ultimate N' }, + 0x00000011 => { ms_const: 'PRODUCT_WEB_SERVER', name: 'Web Server (full installation)' }, + 0x0000001D => { ms_const: 'PRODUCT_WEB_SERVER_CORE', name: 'Web Server (core installation)' }, + }.freeze unless defined?(SKU) + + attr_reader :major_version, :minor_version, :build_number, :service_pack_major_version, :service_pack_minor_version + attr_reader :version, :product_type, :product_suite, :sku + + def initialize + unless RUBY_PLATFORM =~ /mswin|mingw32|windows/ + raise NotImplementedError, 'only valid on Windows platform' + end + @version, @product_type, @product_suite, @sku, @service_pack_major_version, @service_pack_minor_version = get_os_info + @major_version, @minor_version, @build_number = version.split('.').map(&:to_i) + end + + WIN_VERSIONS = { + 'Windows Server 2012 R2' => { major: 6, minor: 3, callable: -> { @product_type != VER_NT_WORKSTATION } }, + 'Windows 8' => { major: 6, minor: 2, callable: -> { @product_type == VER_NT_WORKSTATION } }, + 'Windows Server 2012' => { major: 6, minor: 2, callable: -> { @product_type != VER_NT_WORKSTATION } }, + 'Windows 7' => { major: 6, minor: 1, callable: -> { @product_type == VER_NT_WORKSTATION } }, + 'Windows Server 2008 R2' => { major: 6, minor: 1, callable: -> { @product_type != VER_NT_WORKSTATION } }, + 'Windows Server 2008' => { major: 6, minor: 0, callable: -> { @product_type != VER_NT_WORKSTATION } }, + 'Windows Vista' => { major: 6, minor: 0, callable: -> { @product_type == VER_NT_WORKSTATION } }, + 'Windows Server 2003 R2' => { major: 5, minor: 2, callable: -> { Win32API.new('user32', 'GetSystemMetrics', 'I', 'I').call(SM_SERVERR2) != 0 } }, + 'Windows Home Server' => { major: 5, minor: 2, callable: -> { (@product_suite & VER_SUITE_WH_SERVER) == VER_SUITE_WH_SERVER } }, + 'Windows Server 2003' => { major: 5, minor: 2, callable: -> { Win32API.new('user32', 'GetSystemMetrics', 'I', 'I').call(SM_SERVERR2) == 0 } }, + 'Windows XP' => { major: 5, minor: 1 }, + 'Windows 2000' => { major: 5, minor: 0 }, + }.freeze unless defined?(WIN_VERSIONS) + + marketing_names = [] + + # General Windows checks + WIN_VERSIONS.each do |k, v| + method_name = "#{k.gsub(/\s/, '_').downcase}?" + define_method(method_name) do + (@major_version == v[:major]) && + (@minor_version == v[:minor]) && + (v[:callable] ? v[:callable].call : true) + end + marketing_names << [k, method_name] + end + + define_method(:marketing_name) do + marketing_names.each do |mn| + break mn[0] if send(mn[1]) + end + end + + # Server Type checks + %w( core full datacenter ).each do |m| + define_method("server_#{m}?") do + if @sku + !(SKU[@sku][:name] =~ /#{m}/i).nil? + else + false + end + end + end + + private + + # Win32API call to GetSystemMetrics(SM_SERVERR2) + # returns: The build number if the system is Windows Server 2003 R2; otherwise, 0. + def sm_serverr2 + @sm_serverr2 ||= Win32API.new('user32', 'GetSystemMetrics', 'I', 'I').call(SM_SERVERR2) + end + + # query WMI Win32_OperatingSystem for required OS info + def get_os_info + cols = %w( Version ProductType OSProductSuite OperatingSystemSKU ServicePackMajorVersion ServicePackMinorVersion ) + os_info = execute_wmi_query('select * from Win32_OperatingSystem').each.next + cols.map do |c| + begin + wmi_object_property(os_info, c) + rescue # OperatingSystemSKU doesn't exist in all versions of Windows + nil + end + end + end + end +end diff --git a/cookbooks/windows/libraries/version_helper.rb b/cookbooks/windows/libraries/version_helper.rb new file mode 100644 index 0000000..2b5d4b3 --- /dev/null +++ b/cookbooks/windows/libraries/version_helper.rb @@ -0,0 +1,79 @@ +# +# Cookbook:: windows +# Library:: version_helper +# Author:: Baptiste Courtois () +# +# Copyright:: 2015-2017, Criteo +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +module Windows + # Module based on windows ohai kernel.cs_info providing version helpers + module VersionHelper + # Module referencing CORE SKU contants from product type + # see. https://msdn.microsoft.com/windows/desktop/ms724358#PRODUCT_DATACENTER_SERVER_CORE + # n.b. Prefix - PRODUCT_ - and suffix - _CORE- have been removed + module CoreSKU + # Server Datacenter Core + DATACENTER_SERVER = 0x0C unless constants.include?(:DATACENTER_SERVER) + # Server Datacenter without Hyper-V Core + DATACENTER_SERVER_V = 0x27 unless constants.include?(:DATACENTER_SERVER_V) + # Server Enterprise Core + ENTERPRISE_SERVER = 0x0E unless constants.include?(:ENTERPRISE_SERVER) + # Server Enterprise without Hyper-V Core + ENTERPRISE_SERVER_V = 0x29 unless constants.include?(:ENTERPRISE_SERVER_V) + # Server Standard Core + STANDARD_SERVER = 0x0D unless constants.include?(:STANDARD_SERVER) + # Server Standard without Hyper-V Core + STANDARD_SERVER_V = 0x28 unless constants.include?(:STANDARD_SERVER_V) + end + + # Module referencing product type contants + # see. https://msdn.microsoft.com/windows/desktop/ms724833#VER_NT_SERVER + # n.b. Prefix - VER_NT_ - has been removed + module ProductType + WORKSTATION = 0x1 unless constants.include?(:WORKSTATION) + DOMAIN_CONTROLLER = 0x2 unless constants.include?(:DOMAIN_CONTROLLER) + SERVER = 0x3 unless constants.include?(:SERVER) + end + + # Determines whether current node is running a windows Core version + def self.core_version?(node) + validate_platform node + + CoreSKU.constants.any? { |c| CoreSKU.const_get(c) == node['kernel']['os_info']['operating_system_sku'] } + end + + # Determines whether current node is a workstation version + def self.workstation_version?(node) + validate_platform node + node['kernel']['os_info']['product_type'] == ProductType::WORKSTATION + end + + # Determines whether current node is a server version + def self.server_version?(node) + !workstation_version?(node) + end + + # Determines NT version of the current node + def self.nt_version(node) + validate_platform node + + node['platform_version'].to_f + end + + def self.validate_platform(node) + raise 'Windows helper are only supported on windows platform!' if node['platform'] != 'windows' + end + end +end diff --git a/cookbooks/windows/libraries/windows_architecture_helper.rb b/cookbooks/windows/libraries/windows_architecture_helper.rb deleted file mode 100644 index c8fc736..0000000 --- a/cookbooks/windows/libraries/windows_architecture_helper.rb +++ /dev/null @@ -1,86 +0,0 @@ -# Try to include from core chef, if error then monkey patch it in. - -begin - include Chef::Mixin::WindowsArchitectureHelper -rescue - Chef::Log.debug('Chef::Mixin::WindowsArchitectureHelper not in core version, Monkey patching in.') - - require 'chef/exceptions' - require 'win32/api' if Chef::Platform.windows? - - class Chef - module Mixin - module WindowsArchitectureHelper - def node_windows_architecture(node) - node['kernel']['machine'].to_sym - end - - def wow64_architecture_override_required?(node, desired_architecture) - i386_windows_process? && - node_windows_architecture(node) == :x86_64 && - desired_architecture == :x86_64 - end - - def node_supports_windows_architecture?(node, desired_architecture) - assert_valid_windows_architecture!(desired_architecture) - (node_windows_architecture(node) == :x86_64 || - desired_architecture == :i386) ? true : false - end - - def valid_windows_architecture?(architecture) - (architecture == :x86_64) || (architecture == :i386) - end - - def assert_valid_windows_architecture!(architecture) - unless valid_windows_architecture?(architecture) - raise Chef::Exceptions::Win32ArchitectureIncorrect, - 'The specified architecture was not valid. It must be one of :i386 or :x86_64' - end - end - - def i386_windows_process? - Chef::Platform.windows? && 'X86'.casecmp(ENV['PROCESSOR_ARCHITECTURE']) == 0 - end - - def disable_wow64_file_redirection(node) - original_redirection_state = ['0'].pack('P') - - if (node_windows_architecture(node) == :x86_64) && ::Chef::Platform.windows? - win32_wow_64_disable_wow_64_fs_redirection = - ::Win32::API.new('Wow64DisableWow64FsRedirection', 'P', 'L', 'kernel32') - - succeeded = win32_wow_64_disable_wow_64_fs_redirection.call(original_redirection_state) - - if succeeded == 0 - raise Win32APIError 'Failed to disable Wow64 file redirection' - end - - end - - original_redirection_state - end - - def restore_wow64_file_redirection(node, original_redirection_state) - if (node_windows_architecture(node) == :x86_64) && ::Chef::Platform.windows? - win32_wow_64_revert_wow_64_fs_redirection = - ::Win32::API.new('Wow64RevertWow64FsRedirection', 'P', 'L', 'kernel32') - - succeeded = win32_wow_64_revert_wow_64_fs_redirection.call(original_redirection_state) - - if succeeded == 0 - raise Win32APIError 'Failed to revert Wow64 file redirection' - end - end - end - end - end - end -end - -# Making sure this library is available to Chef::Mixin::PowershellOut -# Required for clients that don't have Chef::Mixin::WindowsArchitectureHelper in -# core chef. -if ::Chef::Platform.windows? - require_relative 'powershell_out' - Chef::Mixin::PowershellOut.send(:include, Chef::Mixin::WindowsArchitectureHelper) -end diff --git a/cookbooks/windows/libraries/windows_helper.rb b/cookbooks/windows/libraries/windows_helper.rb index 75d8566..4d102da 100644 --- a/cookbooks/windows/libraries/windows_helper.rb +++ b/cookbooks/windows/libraries/windows_helper.rb @@ -1,168 +1,174 @@ -# -# Author:: Seth Chisamore () -# Cookbook Name:: windows -# Library:: helper -# -# Copyright:: 2011-2015, Chef Software, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -require 'uri' -require 'Win32API' if Chef::Platform.windows? -require 'chef/exceptions' - -module Windows - module Helper - AUTO_RUN_KEY = 'HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run'.freeze unless defined?(AUTO_RUN_KEY) - ENV_KEY = 'HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment'.freeze unless defined?(ENV_KEY) - ExpandEnvironmentStrings = Win32API.new('kernel32', 'ExpandEnvironmentStrings', %w(P P L), 'L') if Chef::Platform.windows? && !defined?(ExpandEnvironmentStrings) - - # returns windows friendly version of the provided path, - # ensures backslashes are used everywhere - def win_friendly_path(path) - path.gsub(::File::SEPARATOR, ::File::ALT_SEPARATOR || '\\') if path - end - - # account for Window's wacky File System Redirector - # http://msdn.microsoft.com/en-us/library/aa384187(v=vs.85).aspx - # especially important for 32-bit processes (like Ruby) on a - # 64-bit instance of Windows. - def locate_sysnative_cmd(cmd) - if ::File.exist?("#{ENV['WINDIR']}\\sysnative\\#{cmd}") - "#{ENV['WINDIR']}\\sysnative\\#{cmd}" - elsif ::File.exist?("#{ENV['WINDIR']}\\system32\\#{cmd}") - "#{ENV['WINDIR']}\\system32\\#{cmd}" - else - cmd - end - end - - # Create a feature provider dependent value object. - # mainly created becasue Windows Feature names are - # different based on whether dism.exe or servicemanagercmd.exe - # is used for installation - def value_for_feature_provider(provider_hash) - p = Chef::Platform.find_provider_for_node(node, :windows_feature) - key = p.to_s.downcase.split('::').last - provider_hash[key] || provider_hash[key.to_sym] - end - - # singleton instance of the Windows Version checker - def win_version - @win_version ||= Windows::Version.new - end - - # Helper function to properly parse a URI - def as_uri(source) - URI.parse(source) - rescue URI::InvalidURIError - Chef::Log.warn("#{source} was an invalid URI. Trying to escape invalid characters") - URI.parse(URI.escape(source)) - end - - # if a file is local it returns a windows friendly path version - # if a file is remote it caches it locally - def cached_file(source, checksum = nil, windows_path = true) - @installer_file_path ||= begin - - if source =~ /^(file|ftp|http|https):\/\// - uri = as_uri(source) - cache_file_path = "#{Chef::Config[:file_cache_path]}/#{::File.basename(::URI.unescape(uri.path))}" - Chef::Log.debug("Caching a copy of file #{source} at #{cache_file_path}") - r = Chef::Resource::RemoteFile.new(cache_file_path, run_context) - r.source(source) - r.backup(false) - r.checksum(checksum) if checksum - r.run_action(:create) - else - cache_file_path = source - end - - windows_path ? win_friendly_path(cache_file_path) : cache_file_path - end - end - - # Expands the environment variables - def expand_env_vars(path) - # We pick 32k because that is the largest it could be: - # http://msdn.microsoft.com/en-us/library/windows/desktop/ms724265%28v=vs.85%29.aspx - buf = 0.chr * 32 * 1024 # 32k - if ExpandEnvironmentStrings.call(path.dup, buf, buf.length) == 0 - fail Chef::Exceptions::Win32APIError, 'Failed calling ExpandEnvironmentStrings (received 0)' - end - buf.strip - end - - def is_package_installed?(package_name) # rubocop:disable Style/PredicateName - installed_packages.include?(package_name) - end - - def installed_packages - @installed_packages || begin - installed_packages = {} - # Computer\HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall - installed_packages.merge!(extract_installed_packages_from_key(::Win32::Registry::HKEY_LOCAL_MACHINE)) # rescue nil - # 64-bit registry view - # Computer\HKEY_LOCAL_MACHINE\Software\Wow6464Node\Microsoft\Windows\CurrentVersion\Uninstall - installed_packages.merge!(extract_installed_packages_from_key(::Win32::Registry::HKEY_LOCAL_MACHINE, (::Win32::Registry::Constants::KEY_READ | 0x0100))) # rescue nil - # 32-bit registry view - # Computer\HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall - installed_packages.merge!(extract_installed_packages_from_key(::Win32::Registry::HKEY_LOCAL_MACHINE, (::Win32::Registry::Constants::KEY_READ | 0x0200))) # rescue nil - # Computer\HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Uninstall - installed_packages.merge!(extract_installed_packages_from_key(::Win32::Registry::HKEY_CURRENT_USER)) # rescue nil - installed_packages - end - end - - private - - def extract_installed_packages_from_key(hkey = ::Win32::Registry::HKEY_LOCAL_MACHINE, desired = ::Win32::Registry::Constants::KEY_READ) - uninstall_subkey = 'Software\Microsoft\Windows\CurrentVersion\Uninstall' - packages = {} - begin - ::Win32::Registry.open(hkey, uninstall_subkey, desired) do |reg| - reg.each_key do |key, _wtime| - begin - k = reg.open(key, desired) - display_name = begin - k['DisplayName'] - rescue - nil - end - version = begin - k['DisplayVersion'] - rescue - 'NO VERSION' - end - uninstall_string = begin - k['UninstallString'] - rescue - nil - end - if display_name - packages[display_name] = { name: display_name, - version: version, - uninstall_string: uninstall_string } - end - rescue ::Win32::Registry::Error - end - end - end - rescue ::Win32::Registry::Error - end - packages - end - end -end - -Chef::Recipe.send(:include, Windows::Helper) +# +# Author:: Seth Chisamore () +# Cookbook:: windows +# Library:: helper +# +# Copyright:: 2011-2017, Chef Software, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'uri' +require 'Win32API' if Chef::Platform.windows? +require 'chef/exceptions' + +module Windows + module Helper + AUTO_RUN_KEY = 'HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run'.freeze unless defined?(AUTO_RUN_KEY) + ENV_KEY = 'HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment'.freeze unless defined?(ENV_KEY) + ExpandEnvironmentStrings = Win32API.new('kernel32', 'ExpandEnvironmentStrings', %w(P P L), 'L') if Chef::Platform.windows? && !defined?(ExpandEnvironmentStrings) + + # returns windows friendly version of the provided path, + # ensures backslashes are used everywhere + def win_friendly_path(path) + path.gsub(::File::SEPARATOR, ::File::ALT_SEPARATOR || '\\') if path + end + + # account for Window's wacky File System Redirector + # http://msdn.microsoft.com/en-us/library/aa384187(v=vs.85).aspx + # especially important for 32-bit processes (like Ruby) on a + # 64-bit instance of Windows. + def locate_sysnative_cmd(cmd) + if ::File.exist?("#{ENV['WINDIR']}\\sysnative\\#{cmd}") + "#{ENV['WINDIR']}\\sysnative\\#{cmd}" + elsif ::File.exist?("#{ENV['WINDIR']}\\system32\\#{cmd}") + "#{ENV['WINDIR']}\\system32\\#{cmd}" + else + cmd + end + end + + # Create a feature provider dependent value object. + # mainly created becasue Windows Feature names are + # different based on whether dism.exe or servicemanagercmd.exe + # is used for installation + def value_for_feature_provider(provider_hash) + p = Chef::Platform.find_provider_for_node(node, :windows_feature) + key = p.to_s.downcase.split('::').last + provider_hash[key] || provider_hash[key.to_sym] + end + + # singleton instance of the Windows Version checker + def win_version + @win_version ||= Windows::Version.new + end + + # Helper function to properly parse a URI + def as_uri(source) + URI.parse(source) + rescue URI::InvalidURIError + Chef::Log.warn("#{source} was an invalid URI. Trying to escape invalid characters") + URI.parse(URI.escape(source)) + end + + # if a file is local it returns a windows friendly path version + # if a file is remote it caches it locally + def cached_file(source, checksum = nil, windows_path = true) + @installer_file_path ||= begin + + if source =~ %r{^(file|ftp|http|https):\/\/} + uri = as_uri(source) + cache_file_path = "#{Chef::Config[:file_cache_path]}/#{::File.basename(::URI.unescape(uri.path))}" + Chef::Log.debug("Caching a copy of file #{source} at #{cache_file_path}") + remote_file cache_file_path do + source source + backup false + checksum checksum unless checksum.nil? + end.run_action(:create) + else + cache_file_path = source + end + + windows_path ? win_friendly_path(cache_file_path) : cache_file_path + end + end + + # Expands the environment variables + def expand_env_vars(path) + # We pick 32k because that is the largest it could be: + # http://msdn.microsoft.com/en-us/library/windows/desktop/ms724265%28v=vs.85%29.aspx + buf = 0.chr * 32 * 1024 # 32k + if ExpandEnvironmentStrings.call(path.dup, buf, buf.length) == 0 + raise Chef::Exceptions::Win32APIError, 'Failed calling ExpandEnvironmentStrings (received 0)' + end + buf.strip + end + + def is_package_installed?(package_name) # rubocop:disable Style/PredicateName + installed_packages.include?(package_name) + end + + def installed_packages + @installed_packages || begin + installed_packages = {} + # Computer\HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall + installed_packages.merge!(extract_installed_packages_from_key(::Win32::Registry::HKEY_LOCAL_MACHINE)) # rescue nil + # 64-bit registry view + # Computer\HKEY_LOCAL_MACHINE\Software\Wow6464Node\Microsoft\Windows\CurrentVersion\Uninstall + installed_packages.merge!(extract_installed_packages_from_key(::Win32::Registry::HKEY_LOCAL_MACHINE, (::Win32::Registry::Constants::KEY_READ | 0x0100))) # rescue nil + # 32-bit registry view + # Computer\HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall + installed_packages.merge!(extract_installed_packages_from_key(::Win32::Registry::HKEY_LOCAL_MACHINE, (::Win32::Registry::Constants::KEY_READ | 0x0200))) # rescue nil + # Computer\HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Uninstall + installed_packages.merge!(extract_installed_packages_from_key(::Win32::Registry::HKEY_CURRENT_USER)) # rescue nil + installed_packages + end + end + + # Returns an array + def to_array(var) + var = var.is_a?(Array) ? var : [var] + var.reject(&:nil?) + end + + private + + def extract_installed_packages_from_key(hkey = ::Win32::Registry::HKEY_LOCAL_MACHINE, desired = ::Win32::Registry::Constants::KEY_READ) + uninstall_subkey = 'Software\Microsoft\Windows\CurrentVersion\Uninstall' + packages = {} + begin + ::Win32::Registry.open(hkey, uninstall_subkey, desired) do |reg| + reg.each_key do |key, _wtime| + begin + k = reg.open(key, desired) + display_name = begin + k['DisplayName'] + rescue + nil + end + version = begin + k['DisplayVersion'] + rescue + 'NO VERSION' + end + uninstall_string = begin + k['UninstallString'] + rescue + nil + end + if display_name + packages[display_name] = { name: display_name, + version: version, + uninstall_string: uninstall_string } + end + rescue ::Win32::Registry::Error + end + end + end + rescue ::Win32::Registry::Error + end + packages + end + end +end + +Chef::Recipe.send(:include, Windows::Helper) diff --git a/cookbooks/windows/libraries/windows_package.rb b/cookbooks/windows/libraries/windows_package.rb deleted file mode 100644 index f8700f9..0000000 --- a/cookbooks/windows/libraries/windows_package.rb +++ /dev/null @@ -1,226 +0,0 @@ -require 'chef/resource/lwrp_base' -require 'chef/provider/lwrp_base' - -require 'win32/registry' if RUBY_PLATFORM =~ /mswin|mingw32|windows/ - -require 'chef/mixin/shell_out' -require 'chef/mixin/language' -class Chef - class Provider - class WindowsCookbookPackage < Chef::Provider::LWRPBase - include Chef::Mixin::ShellOut - include Windows::Helper - - # the logic in all action methods mirror that of - # the Chef::Provider::Package which will make - # refactoring into core chef easy - - action :install do - # If we specified a version, and it's not the current version, move to the specified version - if !@new_resource.version.nil? && @new_resource.version != @current_resource.version - install_version = @new_resource.version - # If it's not installed at all, install it - elsif @current_resource.version.nil? - install_version = candidate_version - end - - if install_version - Chef::Log.info("Installing #{@new_resource} version #{install_version}") - status = install_package(@new_resource.package_name, install_version) - new_resource.updated_by_last_action(true) if status - end - end - - action :upgrade do - if @current_resource.version != candidate_version - orig_version = @current_resource.version || 'uninstalled' - Chef::Log.info("Upgrading #{@new_resource} version from #{orig_version} to #{candidate_version}") - status = upgrade_package(@new_resource.package_name, candidate_version) - new_resource.updated_by_last_action(true) if status - end - end - - action :remove do - if removing_package? - Chef::Log.info("Removing #{@new_resource}") - remove_package(@current_resource.package_name, @new_resource.version) - new_resource.updated_by_last_action(true) - end - end - - def removing_package? - if @current_resource.version.nil? - false # nothing to remove - elsif @new_resource.version.nil? - true # remove any version of a package - elsif @new_resource.version == @current_resource.version - true # remove the version we have - else - false # we don't have the version we want to remove - end - end - - def expand_options(options) - options ? " #{options}" : '' - end - - # these methods are the required overrides of - # a provider that extends from Chef::Provider::Package - # so refactoring into core Chef should be easy - - def load_current_resource - @current_resource = Chef::Resource::WindowsPackage.new(@new_resource.name) - @current_resource.package_name(@new_resource.package_name) - @current_resource.version(nil) - - unless current_installed_version.nil? - @current_resource.version(current_installed_version) - end - - @current_resource - end - - def current_installed_version - @current_installed_version ||= begin - if installed_packages.include?(@new_resource.package_name) - installed_packages[@new_resource.package_name][:version] - end - end - end - - def candidate_version - @candidate_version ||= begin - @new_resource.version || 'latest' - end - end - - def install_package(_name, _version) - Chef::Log.debug("Processing #{@new_resource} as a #{installer_type} installer.") - install_args = [cached_file(@new_resource.source, @new_resource.checksum), expand_options(unattended_installation_flags), expand_options(@new_resource.options)] - Chef::Log.info('Starting installation...this could take awhile.') - Chef::Log.debug "Install command: #{sprintf(install_command_template, *install_args)}" - shell_out!(sprintf(install_command_template, *install_args), timeout: @new_resource.timeout, returns: @new_resource.success_codes) - end - - def remove_package(_name, _version) - uninstall_string = installed_packages[@new_resource.package_name][:uninstall_string] - Chef::Log.info("Registry provided uninstall string for #{@new_resource} is '#{uninstall_string}'") - uninstall_command = begin - if uninstall_string =~ /msiexec/i - "#{uninstall_string} /qn" - else - uninstall_string.delete!('"') - "start \"\" /wait /d\"#{::File.dirname(uninstall_string)}\" #{::File.basename(uninstall_string)}#{expand_options(@new_resource.options)} /S & exit %%%%ERRORLEVEL%%%%" - end - end - Chef::Log.info("Removing #{@new_resource} with uninstall command '#{uninstall_command}'") - shell_out!(uninstall_command, { returns: @new_resource.success_codes }) - end - - private - - def install_command_template - case installer_type - when :msi - "msiexec%2$s \"%1$s\"%3$s" - else - "start \"\" /wait \"%1$s\"%2$s%3$s & exit %%%%ERRORLEVEL%%%%" - end - end - - # http://unattended.sourceforge.net/installers.php - def unattended_installation_flags - case installer_type - when :msi - # this is no-ui - '/qn /i' - when :installshield - '/s /sms' - when :nsis - '/S /NCRC' - when :inno - # "/sp- /silent /norestart" - '/verysilent /norestart' - when :wise - '/s' - end - end - - def installer_type - @installer_type || begin - if @new_resource.installer_type - @new_resource.installer_type - else - basename = ::File.basename(cached_file(@new_resource.source, @new_resource.checksum)) - if basename.split('.').last.downcase == 'msi' # Microsoft MSI - :msi - else - # search the binary file for installer type - contents = ::Kernel.open(::File.expand_path(cached_file(@new_resource.source)), 'rb', &:read) # TODO: limit data read in - case contents - when /inno/i # Inno Setup - :inno - when /wise/i # Wise InstallMaster - :wise - when /nsis/i # Nullsoft Scriptable Install System - :nsis - else - # if file is named 'setup.exe' assume installshield - if basename == 'setup.exe' - :installshield - else - fail Chef::Exceptions::AttributeNotFound, 'installer_type could not be determined, please set manually' - end - end - end - end - end - end - end - end -end - -class Chef - class Resource - class WindowsCookbookPackage < Chef::Resource::LWRPBase - if Gem::Version.new(Chef::VERSION) >= Gem::Version.new('12.4.0') - provides :windows_package, os: 'windows', override: true - elsif Gem::Version.new(Chef::VERSION) >= Gem::Version.new('12') - provides :windows_package, os: 'windows' - end - actions :install, :remove - - default_action :install - - attribute :package_name, kind_of: String, name_attribute: true - attribute :source, kind_of: String, required: true - attribute :version, kind_of: String - attribute :options, kind_of: String - attribute :installer_type, kind_of: Symbol, default: nil, equal_to: [:msi, :inno, :nsis, :wise, :installshield, :custom] - attribute :checksum, kind_of: String - attribute :timeout, kind_of: Integer, default: 600 - attribute :success_codes, kind_of: Array, default: [0, 42, 127] - - self.resource_name = 'windows_package' - def initialize(*args) - super - @provider = Chef::Provider::WindowsCookbookPackage - end - end - end -end - -if Gem::Version.new(Chef::VERSION) < Gem::Version.new('12') - # this wires up the cookbook version of the windows_package resource as Chef::Resource::WindowsPackage, - # which is kinda hella janky - Chef::Resource.send(:remove_const, :WindowsPackage) if defined? Chef::Resource::WindowsPackage - Chef::Resource.const_set('WindowsPackage', Chef::Resource::WindowsCookbookPackage) -else - if Chef.respond_to?(:set_resource_priority_array) - # this wires up the dynamic resource resolver to favor the cookbook version of windows_package over - # the internal version (but the internal Chef::Resource::WindowsPackage is still the internal version - # and a wrapper cookbook can override this e.g. for users that want to use the windows cookbook but - # want the internal windows_package resource) - Chef.set_resource_priority_array(:windows_package, [Chef::Resource::WindowsCookbookPackage], platform: 'windows') - end -end diff --git a/cookbooks/windows/libraries/windows_privileged.rb b/cookbooks/windows/libraries/windows_privileged.rb index 50b1e4a..5abf08b 100644 --- a/cookbooks/windows/libraries/windows_privileged.rb +++ b/cookbooks/windows/libraries/windows_privileged.rb @@ -1,103 +1,103 @@ -# -# Author:: Doug MacEachern -# Author:: Paul Morton () -# Cookbook Name:: windows -# Library:: windows_privileged -# -# Copyright:: 2010, VMware, Inc. -# Copyright:: 2011, Business Intelligence Associates, Inc -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# helpers for Windows API calls that require privilege adjustments -class Chef - class WindowsPrivileged - # File -> Load Hive... in regedit.exe - def reg_load_key(name, file) - load_deps - - run(SE_BACKUP_NAME, SE_RESTORE_NAME) do - rc = RegLoadKey(HKEY_USERS, name.to_s, file) - if rc == ERROR_SUCCESS - return true - elsif rc == ERROR_SHARING_VIOLATION - return false - else - fail get_last_error(rc) - end - end - end - - # File -> Unload Hive... in regedit.exe - def reg_unload_key(name) - load_deps - - run(SE_BACKUP_NAME, SE_RESTORE_NAME) do - rc = RegUnLoadKey(HKEY_USERS, name.to_s) - fail get_last_error(rc) if rc != ERROR_SUCCESS - end - end - - def run(*privileges) - load_deps - - token = [0].pack('L') - - unless OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, token) - fail get_last_error - end - token = token.unpack('L')[0] - - privileges.each do |name| - unless adjust_privilege(token, name, SE_PRIVILEGE_ENABLED) - fail get_last_error - end - end - - begin - yield - ensure # disable privs - privileges.each do |name| - adjust_privilege(token, name, 0) - end - end - end - - def adjust_privilege(token, priv, attr = 0) - load_deps - - luid = [0, 0].pack('Ll') - if LookupPrivilegeValue(nil, priv, luid) - new_state = [1, luid.unpack('Ll'), attr].flatten.pack('LLlL') - AdjustTokenPrivileges(token, 0, new_state, new_state.size, 0, 0) - end - end - - private - - def load_deps - if RUBY_PLATFORM =~ /mswin|mingw32|windows/ - require 'windows/error' - require 'windows/registry' - require 'windows/process' - require 'windows/security' - - include Windows::Error - include Windows::Registry - include Windows::Process - include Windows::Security - end - end - end -end +# +# Author:: Doug MacEachern +# Author:: Paul Morton () +# Cookbook:: windows +# Library:: windows_privileged +# +# Copyright:: 2010-2017, VMware, Inc. +# Copyright:: 2011-2017, Business Intelligence Associates, Inc +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# helpers for Windows API calls that require privilege adjustments +class Chef + class WindowsPrivileged + # File -> Load Hive... in regedit.exe + def reg_load_key(name, file) + load_deps + + run(SE_BACKUP_NAME, SE_RESTORE_NAME) do + rc = RegLoadKey(HKEY_USERS, name.to_s, file) + if rc == ERROR_SUCCESS + return true + elsif rc == ERROR_SHARING_VIOLATION + return false + else + raise get_last_error(rc) + end + end + end + + # File -> Unload Hive... in regedit.exe + def reg_unload_key(name) + load_deps + + run(SE_BACKUP_NAME, SE_RESTORE_NAME) do + rc = RegUnLoadKey(HKEY_USERS, name.to_s) + raise get_last_error(rc) if rc != ERROR_SUCCESS + end + end + + def run(*privileges) + load_deps + + token = [0].pack('L') + + unless OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, token) + raise get_last_error + end + token = token.unpack('L')[0] + + privileges.each do |name| + unless adjust_privilege(token, name, SE_PRIVILEGE_ENABLED) + raise get_last_error + end + end + + begin + yield + ensure # disable privs + privileges.each do |name| + adjust_privilege(token, name, 0) + end + end + end + + def adjust_privilege(token, priv, attr = 0) + load_deps + + luid = [0, 0].pack('Ll') + if LookupPrivilegeValue(nil, priv, luid) + new_state = [1, luid.unpack('Ll'), attr].flatten.pack('LLlL') + AdjustTokenPrivileges(token, 0, new_state, new_state.size, 0, 0) + end + end + + private + + def load_deps + if RUBY_PLATFORM =~ /mswin|mingw32|windows/ + require 'windows/error' + require 'windows/registry' + require 'windows/process' + require 'windows/security' + + include Windows::Error + include Windows::Registry + include Windows::Process + include Windows::Security + end + end + end +end diff --git a/cookbooks/windows/libraries/wmi_helper.rb b/cookbooks/windows/libraries/wmi_helper.rb index 171a7d2..4d9c609 100644 --- a/cookbooks/windows/libraries/wmi_helper.rb +++ b/cookbooks/windows/libraries/wmi_helper.rb @@ -1,32 +1,32 @@ -# -# Author:: Adam Edwards () -# -# Copyright:: 2014-2015, Chef Software, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -if RUBY_PLATFORM =~ /mswin|mingw32|windows/ - require 'win32ole' - - def execute_wmi_query(wmi_query) - wmi = ::WIN32OLE.connect('winmgmts://') - result = wmi.ExecQuery(wmi_query) - return nil unless result.each.count > 0 - result - end - - def wmi_object_property(wmi_object, wmi_property) - wmi_object.send(wmi_property) - end -end +# +# Author:: Adam Edwards () +# +# Copyright:: 2014-2017, Chef Software, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +if RUBY_PLATFORM =~ /mswin|mingw32|windows/ + require 'win32ole' + + def execute_wmi_query(wmi_query) + wmi = ::WIN32OLE.connect('winmgmts://') + result = wmi.ExecQuery(wmi_query) + return nil unless result.each.count > 0 + result + end + + def wmi_object_property(wmi_object, wmi_property) + wmi_object.send(wmi_property) + end +end diff --git a/cookbooks/windows/metadata.json b/cookbooks/windows/metadata.json index 5fb7396..d959937 100644 --- a/cookbooks/windows/metadata.json +++ b/cookbooks/windows/metadata.json @@ -1 +1 @@ -{"name":"windows","version":"1.38.4","description":"Provides a set of useful Windows-specific primitives.","long_description":"Windows Cookbook\n================\n[![Build Status](https://travis-ci.org/chef-cookbooks/windows.svg?branch=master)](http://travis-ci.org/chef-cookbooks/windows)\n[![Cookbook Version](https://img.shields.io/cookbook/v/windows.svg)](https://supermarket.chef.io/cookbooks/windows)\n\nProvides a set of Windows-specific primitives (Chef resources) meant to aid in the creation of cookbooks/recipes targeting the Windows platform.\n\n\nRequirements\n------------\n#### Platforms\n* Windows Vista\n* Windows 7\n* Windows Server 2008 (R1, R2)\n* Windows 8, 8.1\n* Windows Server 2012 (R1, R2)\n\n#### Chef\n- Chef 11+\n\n#### Cookbooks\n* chef_handler (`windows::reboot_handler` leverages the chef_handler LWRP)\n\n\nAttributes\n----------\n* `node['windows']['allow_pending_reboots']` - used to configure the `WindowsRebootHandler` (via the `windows::reboot_handler` recipe) to act on pending reboots. default is true (ie act on pending reboots). The value of this attribute only has an effect if the `windows::reboot_handler` is in a node's run list.\n* `node['windows']['allow_reboot_on_failure']` - used to register the `WindowsRebootHandler` (via the `windows::reboot_handler` recipe) as an exception handler too to act on reboots not only at the end of successful Chef runs, but even at the end of failed runs. default is false (ie reboot only after successful runs). The value of this attribute only has an effect if the `windows::reboot_handler` is in a node's run list.\n\n\nResource/Provider\n-----------------\n### windows_auto_run\n#### Actions\n- `:create` - Create an item to be run at login\n- `:remove` - Remove an item that was previously setup to run at login\n\n#### Attribute Parameters\n- `name` - Name attribute. The name of the value to be stored in the registry\n- `program` - The program to be run at login\n- `args` - The arguments for the program\n\n#### Examples\nRun BGInfo at login\n\n```ruby\nwindows_auto_run 'BGINFO' do\n program 'C:/Sysinternals/bginfo.exe'\n args '\\'C:/Sysinternals/Config.bgi\\' /NOLICPROMPT /TIMER:0'\n not_if { Registry.value_exists?(AUTO_RUN_KEY, 'BGINFO') }\n action :create\nend\n```\n\n### windows_batch\nThis resource is now deprecated and will be removed in a future version of this cookbook. Chef >= 11.6.0 includes a built-in [batch](http://docs.chef.io/resource_batch.html) resource.\n\nExecute a batch script using the cmd.exe interpreter (much like the script resources for bash, csh, powershell, perl, python and ruby). A temporary file is created and executed like other script resources, rather than run inline. By their nature, Script resources are not idempotent, as they are completely up to the user's imagination. Use the `not_if` or `only_if` meta parameters to guard the resource for idempotence.\n\n#### Actions\n- `:run` - run the batch file\n\n#### Attribute Parameters\n- `command` - name attribute. Name of the command to execute.\n- `code` - quoted string of code to execute.\n- `creates` - a file this command creates - if the file exists, the command will not be run.\n- `cwd` - current working directory to run the command from.\n- `flags` - command line flags to pass to the interpreter when invoking.\n- `user` - A user name or user ID that we should change to before running this command.\n- `group` - A group name or group ID that we should change to before running this command.\n\n#### Examples\n```ruby\nwindows_batch 'unzip_and_move_ruby' do\n code <<-EOH\n 7z.exe x #{Chef::Config[:file_cache_path]}/ruby-1.8.7-p352-i386-mingw32.7z -oC:\\\\source -r -y\n xcopy C:\\\\source\\\\ruby-1.8.7-p352-i386-mingw32 C:\\\\ruby /e /y\n EOH\nend\n```\n\n```ruby\nwindows_batch 'echo some env vars' do\n code <<-EOH\n echo %TEMP%\n echo %SYSTEMDRIVE%\n echo %PATH%\n echo %WINDIR%\n EOH\nend\n```\n\n### windows_certificate\n\nInstalls a certificate into the Windows certificate store from a file, and grants read-only access to the private key for designated accounts.\nDue to current limitations in winrm, installing certificated remotely may not work if the operation requires a user profile. Operations on the local machine store should still work.\n\n#### Actions\n- `:create` - creates or updates a certificate.\n- `:delete` - deletes a certificate.\n- `:acl_add` - adds read-only entries to a certificate's private key ACL.\n\n#### Attribute Parameters\n- `source` - name attribute. The source file (for create and acl_add), thumprint (for delete and acl_add) or subject (for delete).\n- `pfx_password` - the password to access the source if it is a pfx file.\n- `private_key_acl` - array of 'domain\\account' entries to be granted read-only access to the certificate's private key. This is not idempotent.\n- `store_name` - the certificate store to maniplate. One of MY (default : personal store), CA (trusted intermediate store) or ROOT (trusted root store).\n- `user_store` - if false (default) then use the local machine store; if true then use the current user's store.\n\n#### Examples\n```ruby\n# Add PFX cert to local machine personal store and grant accounts read-only access to private key\nwindows_certificate \"c:/test/mycert.pfx\" do\n\tpfx_password\t\"password\"\n\tprivate_key_acl\t[\"acme\\fred\", \"pc\\jane\"]\nend\n```\n\n```ruby\n# Add cert to trusted intermediate store\nwindows_certificate \"c:/test/mycert.cer\" do\n\tstore_name\t\"CA\"\nend\n```\n\n```ruby\n# Remove all certicates matching the subject\nwindows_certificate \"me.acme.com\" do\n\taction :delete\nend\n```\n\n### windows_certificate_binding\n\nBinds a certificate to an HTTP port in order to enable TLS communication.\n\n#### Actions\n- `:create` - creates or updates a binding.\n- `:delete` - deletes a binding.\n\n#### Attribute Parameters\n- `cert_name` - name attribute. The thumprint(hash) or subject that identifies the certicate to be bound.\n- `name_kind` - indicates the type of cert_name. One of :subject (default) or :hash.\n- `address` - the address to bind against. Default is 0.0.0.0 (all IP addresses).\n- `port` - the port to bind against. Default is 443.\n- `app_id` - the GUID that defines the application that owns the binding. Default is the values used by IIS.\n- `store_name` - the store to locate the certificate in. One of MY (default : personal store), CA (trusted intermediate store) or ROOT (trusted root store).\n\n#### Examples\n```ruby\n# Bind the first certificate matching the subject to the default TLS port\nwindows_certificate_binding \"me.acme.com\" do\nend\n```\n\n```ruby\n# Bind a cert from the CA store with the given hash to port 4334\nwindows_certificate_binding \"me.acme.com\" do\n\tcert_name\t\"d234567890a23f567c901e345bc8901d34567890\"\n\tname_kind\t:hash\n\tstore_name\t\"CA\"\n\tport\t\t4334\nend\n```\n\n### windows_feature\nWindows Roles and Features can be thought of as built-in operating system packages that ship with the OS. A server role is a set of software programs that, when they are installed and properly configured, lets a computer perform a specific function for multiple users or other computers within a network. A Role can have multiple Role Services that provide functionality to the Role. Role services are software programs that provide the functionality of a role. Features are software programs that, although they are not directly parts of roles, can support or augment the functionality of one or more roles, or improve the functionality of the server, regardless of which roles are installed. Collectively we refer to all of these attributes as 'features'.\n\nThis resource allows you to manage these 'features' in an unattended, idempotent way.\n\nThere are two providers for the `windows_features` which map into Microsoft's two major tools for managing roles/features: [Deployment Image Servicing and Management (DISM)](http://msdn.microsoft.com/en-us/library/dd371719%28v=vs.85%29.aspx) and [Servermanagercmd](http://technet.microsoft.com/en-us/library/ee344834%28WS.10%29.aspx) (The CLI for Server Manager). As Servermanagercmd is deprecated, Chef will set the default provider to `Chef::Provider::WindowsFeature::DISM` if DISM is present on the system being configured. The default provider will fall back to `Chef::Provider::WindowsFeature::ServerManagerCmd`.\n\nFor more information on Roles, Role Services and Features see the [Microsoft TechNet article on the topic](http://technet.microsoft.com/en-us/library/cc754923.aspx). For a complete list of all features that are available on a node type either of the following commands at a command prompt:\n\n```text\ndism /online /Get-Features\nservermanagercmd -query\n```\n\n#### Actions\n- `:install` - install a Windows role/feature\n- `:remove` - remove a Windows role/feature\n\n#### Attribute Parameters\n- `feature_name` - name of the feature/role to install. The same feature may have different names depending on the provider used (ie DHCPServer vs DHCP; DNS-Server-Full-Role vs DNS).\n- `all` - Boolean. Optional. Default: false. DISM provider only. Forces all dependencies to be installed.\n- `source` - String. Optional. DISM provider only. Uses local repository for feature install.\n\n#### Providers\n- **Chef::Provider::WindowsFeature::DISM**: Uses Deployment Image Servicing and Management (DISM) to manage roles/features.\n- **Chef::Provider::WindowsFeature::ServerManagerCmd**: Uses Server Manager to manage roles/features.\n- **Chef::Provider::WindowsFeaturePowershell**: Uses Powershell to manage roles/features. (see [COOK-3714](https://tickets.chef.io/browse/COOK-3714)\n\n#### Examples\nEnable the node as a DHCP Server\n\n```ruby\nwindows_feature 'DHCPServer' do\n action :install\nend\n```\n\nEnable TFTP\n\n```ruby\nwindows_feature 'TFTP' do\n action :install\nend\n```\n\nEnable .Net 3.5.1 on Server 2012 using repository files on DVD and\ninstall all dependencies\n\n```ruby\nwindows_feature \"NetFx3\" do\n action :install\n all true\n source \"d:\\sources\\sxs\"\nend\n```\n\nDisable Telnet client/server\n\n```ruby\n%w[TelnetServer TelnetClient].each do |feature|\n windows_feature feature do\n action :remove\n end\nend\n```\n\nAdd SMTP Feature with powershell provider\n\n```ruby\nwindows_feature \"smtp-server\" do\n action :install\n all true\n provider :windows_feature_powershell\nend\n```\n\n### windows_font\nInstalls a font.\n\nFont files should be included in the cookbooks\n\n#### Actions\n- `:install` - install a font to the system fonts directory.\n\n#### Attribute Parameters\n- `file` - The name of the font file name to install. It should exist in the files/default directory of the cookbook you're calling windows_font from. Defaults to the resource name.\n\n#### Examples\n\n```ruby\nwindows_font 'Code New Roman.otf'\n```\n\n### windows_http_acl\nSets the Access Control List for an http URL to grant non-admin accounts permission to open HTTP endpoints.\n\n#### Actions\n- `:create` - creates or updates the ACL for a URL.\n- `:delete` - deletes the ACL from a URL.\n\n#### Attribute Parameters\n- `url` - the name of the url to be created/deleted.\n- `user` - the name (domain\\user) of the user or group to be granted permission to the URL. Mandatory for create. Only one user or group can be granted permission so this replaces any previously defined entry.\n\n#### Examples\n\n```ruby\nwindows_http_acl 'http://+:50051/' do\n\tuser 'pc\\\\fred'\nend\n```\n\n```ruby\nwindows_http_acl 'http://+:50051/' do\n\taction :delete\nend\n```\n\n### windows_package\nManage Windows application packages in an unattended, idempotent way.\n\nThe following application installers are currently supported:\n\n* MSI packages\n* InstallShield\n* Wise InstallMaster\n* Inno Setup\n* Nullsoft Scriptable Install System\n\nIf the proper installer type is not passed into the resource's installer_type attribute, the provider will do it's best to identify the type by introspecting the installation package. If the installation type cannot be properly identified the `:custom` value can be passed into the installer_type attribute along with the proper flags for silent/quiet installation (using the `options` attribute..see example below).\n\n__PLEASE NOTE__ - For proper idempotence the resource's `package_name` should be the same as the 'DisplayName' registry value in the uninstallation data that is created during package installation. The easiest way to definitively find the proper 'DisplayName' value is to install the package on a machine and search for the uninstall information under the following registry keys:\n\n* `HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall`\n* `HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall`\n* `HKEY_LOCAL_MACHINE\\Software\\Wow6464Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall`\n\nFor maximum flexibility the `source` attribute supports both remote and local installation packages.\n\n#### Actions\n- `:install` - install a package\n- `:remove` - remove a package. The remove action is completely hit or miss as many application uninstallers do not support a full silent/quiet mode.\n\n#### Attribute Parameters\n- `package_name` - name attribute. The 'DisplayName' of the application installation package.\n- `source` - The source of the windows installer. This can either be a URI or a local path.\n- `installer_type` - They type of windows installation package. Valid values include :msi, :inno, :nsis, :wise, :installshield, :custom. If this value is not provided, the provider will do it's best to identify the installer type through introspection of the file.\n- `checksum` - useful if source is remote, the SHA-256 checksum of the file--if the local file matches the checksum, Chef will not download it\n- `options` - Additional options to pass the underlying installation command\n- `timeout` - set a timeout for the package download (default 600 seconds)\n- `version` - The version number of this package, as indicated by the 'DisplayVersion' value in one of the 'Uninstall' registry keys. If the given version number does equal the 'DisplayVersion' in the registry, the package will be installed.\n- `success_codes` - set an array of possible successful installation\n return codes. Previously this was hardcoded, but certain MSIs may\n have a different return code, e.g. 3010 for reboot required. Must be\n an array, and defaults to `[0, 42, 127]`.\n\n#### Examples\n\nInstall PuTTY (InnoSetup installer)\n```ruby\nwindows_package 'PuTTY version 0.60' do\n source 'http://the.earth.li/~sgtatham/putty/latest/x86/putty-0.60-installer.exe'\n installer_type :inno\n action :install\nend\n```\n\nInstall 7-Zip (MSI installer)\n```ruby\nwindows_package '7-Zip 9.20 (x64 edition)' do\n source 'http://downloads.sourceforge.net/sevenzip/7z920-x64.msi'\n action :install\nend\n```\n\nInstall Notepad++ (Y U No Emacs?) using a local installer\n```ruby\nwindows_package 'Notepad++' do\n source 'c:/installation_files/npp.5.9.2.Installer.exe'\n action :install\nend\n```\n\nInstall VLC for that Xvid (NSIS installer)\n```ruby\nwindows_package 'VLC media player 1.1.10' do\n source 'http://superb-sea2.dl.sourceforge.net/project/vlc/1.1.10/win32/vlc-1.1.10-win32.exe'\n action :install\nend\n```\n\nInstall Firefox as custom installer and manually set the silent install flags\n```ruby\nwindows_package 'Mozilla Firefox 5.0 (x86 en-US)' do\n source 'http://archive.mozilla.org/pub/mozilla.org/mozilla.org/firefox/releases/5.0/win32/en-US/Firefox%20Setup%205.0.exe'\n options '-ms'\n installer_type :custom\n action :install\nend\n```\n\nGoogle Chrome FTW (MSI installer)\n```ruby\nwindows_package 'Google Chrome' do\n source 'https://dl-ssl.google.com/tag/s/appguid%3D%7B8A69D345-D564-463C-AFF1-A69D9E530F96%7D%26iid%3D%7B806F36C0-CB54-4A84-A3F3-0CF8A86575E0%7D%26lang%3Den%26browser%3D3%26usagestats%3D0%26appname%3DGoogle%2520Chrome%26needsadmin%3Dfalse/edgedl/chrome/install/GoogleChromeStandaloneEnterprise.msi'\n action :install\nend\n```\n\nRemove Google Chrome\n```ruby\nwindows_package 'Google Chrome' do\n action :remove\nend\n```\n\nRemove 7-Zip\n```ruby\nwindows_package '7-Zip 9.20 (x64 edition)' do\n action :remove\nend\n```\n\n### windows_printer_port\n\nCreate and delete TCP/IPv4 printer ports.\n\n#### Actions\n- `:create` - Create a TCIP/IPv4 printer port. This is the default action.\n- `:delete` - Delete a TCIP/IPv4 printer port\n\n#### Attribute Parameters\n- `ipv4_address` - Name attribute. Required. IPv4 address, e.g. '10.0.24.34'\n- `port_name` - Port name. Optional. Defaults to 'IP_' + `ipv4_address`\n- `port_number` - Port number. Optional. Defaults to 9100.\n- `port_description` - Port description. Optional.\n- `snmp_enabled` - Boolean. Optional. Defaults to false.\n- `port_protocol` - Port protocol, 1 (RAW), or 2 (LPR). Optional. Defaults to 1.\n\n#### Examples\n\nCreate a TCP/IP printer port named 'IP_10.4.64.37' with all defaults\n```ruby\nwindows_printer_port '10.4.64.37' do\n action :create\nend\n```\n\nDelete a printer port\n```ruby\nwindows_printer_port '10.4.64.37' do\n action :delete\nend\n```\n\nDelete a port with a custom port_name\n```ruby\nwindows_printer_port '10.4.64.38' do\n port_name 'My awesome port'\n action :delete\nend\n```\n\nCreate a port with more options\n```ruby\nwindows_printer_port '10.4.64.39' do\n port_name 'My awesome port'\n snmp_enabled true\n port_protocol 2\nend\n```\n\n### windows_printer\n\nCreate Windows printer. Note that this doesn't currently install a printer\ndriver. You must already have the driver installed on the system.\n\nThe Windows Printer LWRP will automatically create a TCP/IP printer port for you using the `ipv4_address` property. If you want more granular control over the printer port, just create it using the `windows_printer_port` LWRP before creating the printer.\n\n#### Actions\n- `:create` - Create a new printer\n- `:delete` - Delete a new printer\n\n#### Attribute Parameters\n- `device_id` - Name attribute. Required. Printer queue name, e.g. 'HP LJ 5200 in fifth floor copy room'\n- `comment` - Optional string describing the printer queue.\n- `default` - Boolean. Optional. Defaults to false. Note that Windows sets the first printer defined to the default printer regardless of this setting.\n- `driver_name` - String. Required. Exact name of printer driver. Note that the printer driver must already be installed on the node.\n- `location` - Printer location, e.g. 'Fifth floor copy room', or 'US/NYC/Floor42/Room4207'\n- `shared` - Boolean. Defaults to false.\n- `share_name` - Printer share name.\n- `ipv4_address` - Printer IPv4 address, e.g. '10.4.64.23'. You don't have to be able to ping the IP addresss to set it. Required.\n\nAn error of \"Set-WmiInstance : Generic failure\" is most likely due to the printer driver name not matching or not being installed.\n\n#### Examples\n\nCreate a printer\n```ruby\nwindows_printer 'HP LaserJet 5th Floor' do\n driver_name 'HP LaserJet 4100 Series PCL6'\n ipv4_address '10.4.64.38'\nend\n```\n\nDelete a printer. Note: this doesn't delete the associated printer port. See `windows_printer_port` above for how to delete the port.\n```ruby\nwindows_printer 'HP LaserJet 5th Floor' do\n action :delete\nend\n```\n\n### windows_reboot\nThis resource is now deprecated and will be removed in a future version of this cookbook. Chef >= 12.0.0 includes a built-in [reboot](http://docs.chef.io/resource_reboot.html) resource.\n\nSets required data in the node's run_state to notify `WindowsRebootHandler` a reboot is requested. If Chef run completes successfully a reboot will occur if the `WindowsRebootHandler` is properly registered as a report handler. As an action of `:request` will cause a node to reboot every Chef run, this resource is usually notified by other resources...ie restart node after a package is installed (see example below).\n\n#### Actions\n- `:request` - requests a reboot at completion of successful Cher run. requires `WindowsRebootHandler` to be registered as a report handler.\n- `:cancel` - remove reboot request from node.run_state. this will cancel *ALL* previously requested reboots as this is a binary state.\n\n#### Attribute Parameters\n- `timeout` - Name attribute. timeout delay in seconds to wait before proceeding with the requested reboot. default is 60 seconds\n- `reason` - comment on the reason for the reboot. default is 'Chef Software Chef initiated reboot'\n\n#### Examples\nIf the package installs, schedule a reboot at end of chef run\n```ruby\nwindows_reboot 60 do\n reason 'cause chef said so'\n action :nothing\nend\n\nwindows_package 'some_package' do\n action :install\n notifies :request, 'windows_reboot[60]'\nend\n```\n\nCancel the previously requested reboot\n```ruby\nwindows_reboot 60 do\n action :cancel\nend\n```\n\n### windows_registry\nThis resource is now deprecated and will be removed in a future version of this cookbook. Chef >= 11.6.0 includes a built-in [registry_key](http://docs.chef.io/resource_registry_key.html) resource.\n\nCreates and modifies Windows registry keys.\n\n*Change in v1.3.0: The Win32 classes use `::Win32` to avoid namespace conflict with `Chef::Win32` (introduced in Chef 0.10.10).*\n\n#### Actions\n- `:create` - create a new registry key with the provided values.\n- `:modify` - modify an existing registry key with the provided values.\n- `:force_modify` - modify an existing registry key with the provided values. ensures the value is actually set by checking multiple times. useful for fighting race conditions where two processes are trying to set the same registry key. This will be updated in the near future to use 'RegNotifyChangeKeyValue' which is exposed by the WinAPI and allows a process to register for notification on a registry key change.\n- `:remove` - removes a value from an existing registry key\n\n#### Attribute Parameters\n- `key_name` - name attribute. The registry key to create/modify.\n- `values` - hash of the values to set under the registry key. The individual hash items will become respective 'Value name' => 'Value data' items in the registry key.\n- `type` - Type of key to create, defaults to REG_SZ. Must be a symbol, see the overview below for valid values.\n\n#### Registry key types\n- `:binary` - REG_BINARY\n- `:string` - REG_SZ\n- `:multi_string` - REG_MULTI_SZ\n- `:expand_string` - REG_EXPAND_SZ\n- `:dword` - REG_DWORD\n- `:dword_big_endian` - REG_DWORD_BIG_ENDIAN\n- `:qword` - REG_QWORD\n\n#### Examples\n\nMake the local windows proxy match the one set for Chef\n```ruby\nproxy = URI.parse(Chef::Config[:http_proxy])\nwindows_registry 'HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings' do\n values 'ProxyEnable' => 1, 'ProxyServer' => \"#{proxy.host}:#{proxy.port}\", 'ProxyOverride' => ''\nend\n```\n\nEnable Remote Desktop and poke the firewall hole\n```ruby\nwindows_registry 'HKLM\\SYSTEM\\CurrentControlSet\\Control\\Terminal Server' do\n values 'FdenyTSConnections' => 0\nend\n```\n\nDelete an item from the registry\n```ruby\nwindows_registry 'HKCU\\Software\\Test' do\n #Key is the name of the value that you want to delete the value is always empty\n values 'ValueToDelete' => ''\n action :remove\nend\n```\n\nAdd a REG_MULTI_SZ value to the registry\n```ruby\nwindows_registry 'HKCU\\Software\\Test' do\n values 'MultiString' => ['line 1', 'line 2', 'line 3']\n type :multi_string\nend\n```\n\n### windows_shortcut\nCreates and modifies Windows shortcuts.\n\n#### Actions\n- `:create` - create or modify a windows shortcut\n\n#### Attribute Parameters\n- `name` - name attribute. The shortcut to create/modify.\n- `target` - what the shortcut links to\n- `arguments` - arguments to pass to the target when the shortcut is executed\n- `description` - description of the shortcut\n- `cwd` - Working directory to use when the target is executed\n- `iconlocation` - Icon to use, in the format of ```\"path, index\"``` where index is which icon in that file to use (See [WshShortcut.IconLocation](https://msdn.microsoft.com/en-us/library/3s9bx7at.aspx))\n\n#### Examples\n\nAdd a shortcut all users desktop:\n```ruby\nrequire 'win32ole'\nall_users_desktop = WIN32OLE.new(\"WScript.Shell\").SpecialFolders(\"AllUsersDesktop\")\n\nwindows_shortcut \"#{all_users_desktop}/Notepad.lnk\" do\n target \"C:\\\\WINDOWS\\\\notepad.exe\"\n description \"Launch Notepad\"\n iconlocation \"C:\\\\windows\\\\notepad.exe, 0\"\nend\n```\n\n#### Library Methods\n\n```ruby\nRegistry.value_exists?('HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run','BGINFO')\nRegistry.key_exists?('HKLM\\SOFTWARE\\Microsoft')\nBgInfo = Registry.get_value('HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run','BGINFO')\n```\n\n### windows_path\n#### Actions\n- `:add` - Add an item to the system path\n- `:remove` - Remove an item from the system path\n\n#### Attribute Parameters\n- `path` - Name attribute. The name of the value to add to the system path\n\n#### Examples\n\nAdd Sysinternals to the system path\n```ruby\nwindows_path 'C:\\Sysinternals' do\n action :add\nend\n```\n\nRemove 7-Zip from the system path\n```ruby\nwindows_path 'C:\\7-Zip' do\n action :remove\nend\n```\n\n### windows_task\nCreates, deletes or runs a Windows scheduled task. Requires Windows\nServer 2008 due to API usage.\n\n#### Actions\n- `:create` - creates a task (or updates existing if user or command has changed)\n- `:delete` - deletes a task\n- `:run` - runs a task\n- `:end` - ends a task\n- `:change` - changes the un/pw or command of a task\n- `:enable` - enable a task\n- `:disable` - disable a task\n\n#### Attribute Parameters\n- `task_name` - name attribute, The task name. (\"Task Name\" or \"/Task Name\")\n- `force` - When used with create, will update the task.\n- `command` - The command the task will run.\n- `cwd` - The directory the task will be run from.\n- `user` - The user to run the task as. (defaults to 'SYSTEM')\n- `password` - The user's password. (requires user)\n- `run_level` - Run with `:limited` or `:highest` privileges.\n- `frequency` - Frequency with which to run the task. (default is :hourly. Other valid values include :minute, :hourly, :daily, :weekly, :monthly, :once, :on_logon, :onstart, :on_idle) \\*:once requires start_time\n- `frequency_modifier` - Multiple for frequency. (15 minutes, 2 days)\n- `start_day` - Specifies the first date on which the task runs. Optional string (MM/DD/YYYY)\n- `start_time` - Specifies the start time to run the task. Optional string (HH:mm)\n- `interactive_enabled` - (Allow task to run interactively or non-interactively. Requires user and password.)\n- `day` - For monthly or weekly tasks, the day(s) on which the task runs. (MON - SUN, *, 1 - 31)\n\n#### Examples\n\nCreate a `chef-client` task with TaskPath `\\` running every 15 minutes\n```ruby\nwindows_task 'chef-client' do\n user 'Administrator'\n password '$ecR3t'\n cwd 'C:\\\\chef\\\\bin'\n command 'chef-client -L C:\\\\tmp\\\\'\n run_level :highest\n frequency :minute\n frequency_modifier 15\nend\n```\n\nUpdate `chef-client` task with new password and log location\n```ruby\nwindows_task 'chef-client' do\n user 'Administrator'\n password 'N3wPassW0Rd'\n cwd 'C:\\\\chef\\\\bin'\n command 'chef-client -L C:\\\\chef\\\\logs\\\\'\n action :change\nend\n```\n\nDelete a taks named `old task`\n```ruby\nwindows_task 'old task' do\n action :delete\nend\n```\n\nEnable a task named `chef-client`\n```ruby\nwindows_task 'chef-client' do\n action :enable\nend\n```\n\nDisable a task named `ProgramDataUpdater` with TaskPath `\\Microsoft\\Windows\\Application Experience\\`\n```ruby\nwindows_task '\\Microsoft\\Windows\\Application Experience\\ProgramDataUpdater' do\n action :disable\nend\n```\n\n### windows_zipfile\nMost version of Windows do not ship with native cli utility for managing compressed files. This resource provides a pure-ruby implementation for managing zip files. Be sure to use the `not_if` or `only_if` meta parameters to guard the resource for idempotence or action will be taken every Chef run.\n\n#### Actions\n- `:unzip` - unzip a compressed file\n- `:zip` - zip a directory (recursively)\n\n#### Attribute Parameters\n- `path` - name attribute. The path where files will be (un)zipped to.\n- `source` - source of the zip file (either a URI or local path) for :unzip, or directory to be zipped for :zip.\n- `overwrite` - force an overwrite of the files if they already exist.\n- `checksum` - for :unzip, useful if source is remote, if the local file matches the SHA-256 checksum, Chef will not download it.\n\n#### Examples\n\nUnzip a remote zip file locally\n```ruby\nwindows_zipfile 'c:/bin' do\n source 'http://download.sysinternals.com/Files/SysinternalsSuite.zip'\n action :unzip\n not_if {::File.exists?('c:/bin/PsExec.exe')}\nend\n```\n\nUnzip a local zipfile\n```ruby\nwindows_zipfile 'c:/the_codez' do\n source 'c:/foo/baz/the_codez.zip'\n action :unzip\nend\n```\n\nCreate a local zipfile\n```ruby\nwindows_zipfile 'c:/foo/baz/the_codez.zip' do\n source 'c:/the_codez'\n action :zip\nend\n```\n\nLibraries\n-------------------------\n### WindowsHelper\n\nHelper that allows you to use helpful functions in windows\n\n#### installed_packages\nReturns a hash of all DisplayNames installed\n```ruby\n# usage in a recipe\n::Chef::Recipe.send(:include, Windows::Helper)\nhash_of_installed_packages = installed_packages\n```\n\n#### is_package_installed?\n- `package_name` - The name of the package you want to query to see if it is installed\n- `returns` - true if the package is installed, false if it the package is not installed\n\nDownload a file if a package isn't installed\n```ruby\n# usage in a recipe to not download a file if package is already installed\n::Chef::Recipe.send(:include, Windows::Helper)\nis_win_sdk_installed = is_package_installed?('Windows Software Development Kit')\n\nremote_file 'C:\\windows\\temp\\windows_sdk.zip' do\n source 'http://url_to_download/windows_sdk.zip'\n action :create_if_missing\n not_if {is_win_sdk_installed}\nend\n```\nDo something if a package is installed\n```ruby\n# usage in a provider\ninclude Windows::Helper\nif is_package_installed?('Windows Software Development Kit')\n # do something if package is installed\nend\n```\n\nException/Report Handlers\n-------------------------\n### WindowsRebootHandler\nRequired reboots are a necessary evil of configuring and managing Windows nodes. This report handler (ie fires at the end of Chef runs) acts on requested (Chef initiated) or pending (as determined by the OS per configuration action we performed) reboots. The `allow_pending_reboots` initialization argument should be set to false if you do not want the handler to automatically reboot a node if it has been determined a reboot is pending. Reboots can still be requested explicitly via the `windows_reboot` LWRP.\n\n### Initialization Arguments\n- `allow_pending_reboots` - indicator on whether the handler should act on a the Window's 'pending reboot' state. default is true\n- `timeout` - timeout delay in seconds to wait before proceeding with the reboot. default is 60 seconds\n- `reason` - comment on the reason for the reboot. default is 'Chef Software Chef initiated reboot'\n\n\nWindows ChefSpec Matchers\n-------------------------\nThe Windows cookbook includes custom [ChefSpec](https://github.com/sethvargo/chefspec) matchers you can use to test your own cookbooks that consume Windows cookbook LWRPs.\n\n###Example Matcher Usage\n```ruby\nexpect(chef_run).to install_windows_package('Node.js').with(\n source: 'http://nodejs.org/dist/v0.10.26/x64/node-v0.10.26-x64.msi')\n```\n\n###Windows Cookbook Matchers\n* install_windows_package\n* remove_windows_package\n* install_windows_feature\n* remove_windows_feature\n* delete_windows_feature\n* create_windows_task\n* delete_windows_task\n* run_windows_task\n* change_windows_task\n* add_windows_path\n* remove_windows_path\n* run_windows_batch\n* set_windows_pagefile\n* unzip_windows_zipfile_to\n* zip_windows_zipfile_to\n* create_windows_shortcut\n* create_windows_auto_run\n* remove_windows_auto_run\n* create_windows_printer\n* delete_windows_printer\n* create_windows_printer_port\n* delete_windows_printer_port\n* request_windows_reboot\n* cancel_windows_reboot\n* create_windows_shortcut\n\n\nUsage\n-----\n\nPlace an explicit dependency on this cookbook (using depends in the cookbook's metadata.rb) from any cookbook where you would like to use the Windows-specific resources/providers that ship with this cookbook.\n\n```ruby\ndepends 'windows'\n```\n\n### default\nConvenience recipe that installs supporting gems for many of the resources/providers that ship with this cookbook.\n\n### reboot_handler\nLeverages the `chef_handler` LWRP to register the `WindowsRebootHandler` report handler that ships as part of this cookbook. By default this handler is set to automatically act on pending reboots. If you would like to change this behavior override `node['windows']['allow_pending_reboots']` and set the value to false. For example:\n\n```ruby\nname 'base'\ndescription 'base role'\noverride_attributes(\n 'windows' => {\n 'allow_pending_reboots' => false\n }\n)\n```\n\nThis will still allow a reboot to be explicitly requested via the `windows_reboot` LWRP.\n\nBy default, the handler will only be registered as a report handler, meaning that it will only fire at the end of successful Chef runs. If the run fails, pending or requested reboots will be ignored. This can lead to a situation where some package was installed and notified a reboot request via the `windows_reboot` LWRP, and then the run fails for some unrelated reason, and the reboot request gets dropped because the resource that notified the reboot request will already be up-to-date at the next run and will not request a reboot again, and thus the requested reboot will never be performed. To change this behavior and register the handler as an exception handler that fires at the end of failed runs too, override `node['windows']['allow_reboot_on_failure']` and set the value to true.\n\n\nLicense & Authors\n-----------------\n- Author:: Seth Chisamore ()\n- Author:: Doug MacEachern ()\n- Author:: Paul Morton ()\n- Author:: Doug Ireton ()\n\n```text\nCopyright 2011-2015, Chef Software, Inc.\nCopyright 2010, VMware, Inc.\nCopyright 2011, Business Intelligence Associates, Inc\nCopyright 2012, Nordstrom, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```\n","maintainer":"Chef Software, Inc.","maintainer_email":"cookbooks@chef.io","license":"Apache 2.0","platforms":{"windows":">= 0.0.0"},"dependencies":{"chef_handler":">= 0.0.0"},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{}} \ No newline at end of file +{"name":"windows","version":"3.1.1","description":"Provides a set of useful Windows-specific primitives.","long_description":"# Windows Cookbook\n\n[![Build status](https://ci.appveyor.com/api/projects/status/9x4uepmm1g4rktie/branch/master?svg=true)](https://ci.appveyor.com/project/ChefWindowsCookbooks/windows/branch/master) [![Cookbook Version](https://img.shields.io/cookbook/v/windows.svg)](https://supermarket.chef.io/cookbooks/windows)\n\nProvides a set of Windows-specific resources to aid in the creation of cookbooks/recipes targeting the Windows platform.\n\n## Requirements\n\n### Platforms\n\n- Windows 7\n- Windows Server 2008 R2\n- Windows 8, 8.1\n- Windows Server 2012 (R1, R2)\n\n### Chef\n\n- Chef 12.6+\n\n## Resources\n\n### windows_auto_run\n\n#### Actions\n\n- `:create` - Create an item to be run at login\n- `:remove` - Remove an item that was previously setup to run at login\n\n#### Properties\n\n- `name` - Name attribute. The name of the value to be stored in the registry\n- `program` - The program to be run at login\n- `args` - The arguments for the program\n\n#### Examples\n\nRun BGInfo at login\n\n```ruby\nwindows_auto_run 'BGINFO' do\n program 'C:/Sysinternals/bginfo.exe'\n args '\\'C:/Sysinternals/Config.bgi\\' /NOLICPROMPT /TIMER:0'\n action :create\nend\n```\n\n### windows_certificate\n\nInstalls a certificate into the Windows certificate store from a file, and grants read-only access to the private key for designated accounts. Due to current limitations in WinRM, installing certificated remotely may not work if the operation requires a user profile. Operations on the local machine store should still work.\n\n#### Actions\n\n- `:create` - creates or updates a certificate.\n- `:delete` - deletes a certificate.\n- `:acl_add` - adds read-only entries to a certificate's private key ACL.\n\n#### Properties\n\n- `source` - name attribute. The source file (for create and acl_add), thumbprint (for delete and acl_add) or subject (for delete).\n- `pfx_password` - the password to access the source if it is a pfx file.\n- `private_key_acl` - array of 'domain\\account' entries to be granted read-only access to the certificate's private key. This is not idempotent.\n- `store_name` - the certificate store to manipulate. One of MY (default : personal store), CA (trusted intermediate store) or ROOT (trusted root store).\n- `user_store` - if false (default) then use the local machine store; if true then use the current user's store.\n\n#### Examples\n\n```ruby\n# Add PFX cert to local machine personal store and grant accounts read-only access to private key\nwindows_certificate \"c:/test/mycert.pfx\" do\n pfx_password \"password\"\n private_key_acl [\"acme\\fred\", \"pc\\jane\"]\nend\n```\n\n```ruby\n# Add cert to trusted intermediate store\nwindows_certificate \"c:/test/mycert.cer\" do\n store_name \"CA\"\nend\n```\n\n```ruby\n# Remove all certificates matching the subject\nwindows_certificate \"me.acme.com\" do\n action :delete\nend\n```\n\n### windows_certificate_binding\n\nBinds a certificate to an HTTP port in order to enable TLS communication.\n\n#### Actions\n\n- `:create` - creates or updates a binding.\n- `:delete` - deletes a binding.\n\n#### Properties\n\n- `cert_name` - name attribute. The thumbprint(hash) or subject that identifies the certificate to be bound.\n- `name_kind` - indicates the type of cert_name. One of :subject (default) or :hash.\n- `address` - the address to bind against. Default is 0.0.0.0 (all IP addresses).\n- `port` - the port to bind against. Default is 443.\n- `app_id` - the GUID that defines the application that owns the binding. Default is the values used by IIS.\n- `store_name` - the store to locate the certificate in. One of MY (default : personal store), CA (trusted intermediate store) or ROOT (trusted root store).\n\n#### Examples\n\n```ruby\n# Bind the first certificate matching the subject to the default TLS port\nwindows_certificate_binding \"me.acme.com\" do\nend\n```\n\n```ruby\n# Bind a cert from the CA store with the given hash to port 4334\nwindows_certificate_binding \"me.acme.com\" do\n cert_name \"d234567890a23f567c901e345bc8901d34567890\"\n name_kind :hash\n store_name \"CA\"\n port 4334\nend\n```\n\n### windows_feature\n\n**BREAKING CHANGE - Version 3.0.0**\n\nThis resource has been moved from using LWRPs and multiple providers to using Custom Resources. To maintain functionality, you'll need to change `provider` to `install_method`.\n\nWindows Roles and Features can be thought of as built-in operating system packages that ship with the OS. A server role is a set of software programs that, when they are installed and properly configured, lets a computer perform a specific function for multiple users or other computers within a network. A Role can have multiple Role Services that provide functionality to the Role. Role services are software programs that provide the functionality of a role. Features are software programs that, although they are not directly parts of roles, can support or augment the functionality of one or more roles, or improve the functionality of the server, regardless of which roles are installed. Collectively we refer to all of these attributes as 'features'.\n\nThis resource allows you to manage these 'features' in an unattended, idempotent way.\n\nThere are three methods for the `windows_feature` which map into Microsoft's three major tools for managing roles/features: [Deployment Image Servicing and Management (DISM)](http://msdn.microsoft.com/en-us/library/dd371719%28v=vs.85%29.aspx), [Servermanagercmd](http://technet.microsoft.com/en-us/library/ee344834%28WS.10%29.aspx) (The CLI for Server Manager), and [PowerShell](https://technet.microsoft.com/en-us/library/cc731774(v=ws.11).aspx). As Servermanagercmd is deprecated, Chef will set the default method to `:windows_feature_dism` if `dism.exe` is present on the system being configured. The default method will fall back to `:windows_feature_servermanagercmd`, and then `:windows_feature_powershell`.\n\nFor more information on Roles, Role Services and Features see the [Microsoft TechNet article on the topic](http://technet.microsoft.com/en-us/library/cc754923.aspx). For a complete list of all features that are available on a node type either of the following commands at a command prompt:\n\nFor Dism:\n\n```text\ndism /online /Get-Features\n```\n\nFor ServerManagerCmd:\n\n```text\nservermanagercmd -query\n```\n\nFor PowerShell:\n\n```text\nget-windowsfeature\n```\n\n#### Actions\n\n- `:install` - install a Windows role/feature\n- `:remove` - remove a Windows role/feature\n- `:delete` - remove a Windows role/feature from the image (not supported by ServerManagerCmd)\n\n#### Properties\n\n- `feature_name` - name of the feature/role(s) to install. The same feature may have different names depending on the provider used (ie DHCPServer vs DHCP; DNS-Server-Full-Role vs DNS).\n- `all` - Boolean. Optional. Default: false. DISM and Powershell providers only. Forces all dependencies to be installed.\n- `source` - String. Optional. DISM provider only. Uses local repository for feature install.\n- `install_method` - Symbol. Optional. **REPLACEMENT FOR THE PREVIOUS PROVIDER OPTION** If not supplied, Chef will determine which method to use (in the order of `:windows_feature_dism`, `:windows_feature_servercmd`, `:windows_feature_powershell`)\n\n#### Examples\n\nInstall the DHCP Server feature\n\n```ruby\nwindows_feature 'DHCPServer' do\n action :install\nend\n```\n\nInstall the .Net 3.5.1 feature on Server 2012 using repository files on DVD and install all dependencies\n\n```ruby\nwindows_feature \"NetFx3\" do\n action :install\n all true\n source \"d:\\sources\\sxs\"\nend\n```\n\nRemove Telnet Server and Client features\n\n```ruby\nwindows_feature ['TelnetServer', 'TelnetClient'] do\n action :remove\nend\n```\n\nAdd the SMTP Server feature using the PowerShell provider\n\n```ruby\nwindows_feature \"smtp-server\" do\n action :install\n all true\n install_method :windows_feature_powershell\nend\n```\n\nInstall multiple features using one resource with the PowerShell provider\n\n```ruby\nwindows_feature ['Web-Asp-Net45', 'Web-Net-Ext45'] do\n action :install\n install_method :windows_feature_powershell\nend\n```\n\n### windows_font\n\nInstalls a font.\n\nFont files should be included in the cookbooks\n\n#### Actions\n\n- `:install` - install a font to the system fonts directory.\n\n#### Properties\n\n- `name` - The file name of the font file name to install. The path defaults to the files/default directory of the cookbook you're calling windows_font from. Defaults to the resource name.\n- `source` - Set an alternate path to the font file.\n\n#### Examples\n\n```ruby\nwindows_font 'Code New Roman.otf'\n```\n\n### windows_http_acl\n\nSets the Access Control List for an http URL to grant non-admin accounts permission to open HTTP endpoints.\n\n#### Actions\n\n- `:create` - creates or updates the ACL for a URL.\n- `:delete` - deletes the ACL from a URL.\n\n#### Properties\n\n- `url` - the name of the url to be created/deleted.\n- `sddl` - the DACL string configuring all permissions to URL. Mandatory for create if user is not provided. Can't be use with `user`.\n- `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.\n\n#### Examples\n\n```ruby\nwindows_http_acl 'http://+:50051/' do\n user 'pc\\\\fred'\nend\n```\n\n```ruby\n# Grant access to users \"NT SERVICE\\WinRM\" and \"NT SERVICE\\Wecsvc\" via sddl\nwindows_http_acl 'http://+:5985/' do\n sddl 'D:(A;;GX;;;S-1-5-80-569256582-2953403351-2909559716-1301513147-412116970)(A;;GX;;;S-1-5-80-4059739203-877974739-1245631912-527174227-2996563517)'\nend\n```\n\n```ruby\nwindows_http_acl 'http://+:50051/' do\n action :delete\nend\n```\n\n### windows_pagefile\n\nConfigures the file that provides virtual memory for applications requiring more memory than available RAM or that are paged out to free up memory in use.\n\n\n#### Actions\n\n- `:set` - configures the default pagefile, creating if it doesn't exist.\n- `:delete` - deletes the specified pagefile.\n\n#### Properties\n\n- `name` - the path to the pagefile, String, name_property: true\n- `system_managed` - configures whether the system manages the pagefile size. [true, false]\n- `automatic_managed` - all of the settings are managed by the system. If this is set to true, other settings will be ignored. [true, false], default: false\n- `initial_size` - initial size of the pagefile in bytes. Integer\n- `maximum_size` - maximum size of the pagefile in bytes. Integer\n\n### windows_printer_port\n\nCreate and delete TCP/IPv4 printer ports.\n\n#### Actions\n\n- `:create` - Create a TCIP/IPv4 printer port. This is the default action.\n- `:delete` - Delete a TCIP/IPv4 printer port\n\n#### Properties\n\n- `ipv4_address` - Name attribute. Required. IPv4 address, e.g. '10.0.24.34'\n- `port_name` - Port name. Optional. Defaults to 'IP_' + `ipv4_address`\n- `port_number` - Port number. Optional. Defaults to 9100.\n- `port_description` - Port description. Optional.\n- `snmp_enabled` - Boolean. Optional. Defaults to false.\n- `port_protocol` - Port protocol, 1 (RAW), or 2 (LPR). Optional. Defaults to 1.\n\n#### Examples\n\nCreate a TCP/IP printer port named 'IP_10.4.64.37' with all defaults\n\n```ruby\nwindows_printer_port '10.4.64.37' do\n action :create\nend\n```\n\nDelete a printer port\n\n```ruby\nwindows_printer_port '10.4.64.37' do\n action :delete\nend\n```\n\nDelete a port with a custom port_name\n\n```ruby\nwindows_printer_port '10.4.64.38' do\n port_name 'My awesome port'\n action :delete\nend\n```\n\nCreate a port with more options\n\n```ruby\nwindows_printer_port '10.4.64.39' do\n port_name 'My awesome port'\n snmp_enabled true\n port_protocol 2\nend\n```\n\n### windows_printer\n\nCreate Windows printer. Note that this doesn't currently install a printer driver. You must already have the driver installed on the system.\n\nThe Windows Printer LWRP will automatically create a TCP/IP printer port for you using the `ipv4_address` property. If you want more granular control over the printer port, just create it using the `windows_printer_port` LWRP before creating the printer.\n\n#### Actions\n\n- `:create` - Create a new printer\n- `:delete` - Delete a new printer\n\n#### Properties\n\n- `device_id` - Name attribute. Required. Printer queue name, e.g. 'HP LJ 5200 in fifth floor copy room'\n- `comment` - Optional string describing the printer queue.\n- `default` - Boolean. Optional. Defaults to false. Note that Windows sets the first printer defined to the default printer regardless of this setting.\n- `driver_name` - String. Required. Exact name of printer driver. Note that the printer driver must already be installed on the node.\n- `location` - Printer location, e.g. 'Fifth floor copy room', or 'US/NYC/Floor42/Room4207'\n- `shared` - Boolean. Defaults to false.\n- `share_name` - Printer share name.\n- `ipv4_address` - Printer IPv4 address, e.g. '10.4.64.23'. You don't have to be able to ping the IP address to set it. Required.\n\nAn error of \"Set-WmiInstance : Generic failure\" is most likely due to the printer driver name not matching or not being installed.\n\n#### Examples\n\nCreate a printer\n\n```ruby\nwindows_printer 'HP LaserJet 5th Floor' do\n driver_name 'HP LaserJet 4100 Series PCL6'\n ipv4_address '10.4.64.38'\nend\n```\n\nDelete a printer. Note: this doesn't delete the associated printer port. See `windows_printer_port` above for how to delete the port.\n\n```ruby\nwindows_printer 'HP LaserJet 5th Floor' do\n action :delete\nend\n```\n\n### windows_share\n\nCreates, modifies and removes Windows shares. All properties are idempotent.\n\n#### Actions\n\n- :create: creates/modifies a share\n- :delete: deletes a share\n\n#### Properties\n\n- share_name: name attribute, the share name.\n- path: path to the directory to be shared. Required when creating. If the share already exists on a different path then it is deleted and re-created.\n- description: description to be applied to the share\n- full_users: array of users which should have \"Full control\" permissions\n- change_users: array of users which should have \"Change\" permissions\n- read_users: array of users which should have \"Read\" permissions\n\n#### Examples\n\n```ruby\nwindows_share \"foo\" do\n action :create\n path \"C:\\\\foo\"\n full_users [\"DOMAIN_A\\\\some_user\", \"DOMAIN_B\\\\some_other_user\"]\n read_users [\"DOMAIN_C\\\\Domain users\"]\nend\n```\n\n```ruby\nwindows_share \"foo\" do\n action :delete\nend\n```\n\n### windows_shortcut\n\nCreates and modifies Windows shortcuts.\n\n#### Actions\n\n- `:create` - create or modify a windows shortcut\n\n#### Properties\n\n- `name` - name attribute. The shortcut to create/modify.\n- `target` - what the shortcut links to\n- `arguments` - arguments to pass to the target when the shortcut is executed\n- `description` - description of the shortcut\n- `cwd` - Working directory to use when the target is executed\n- `iconlocation` - Icon to use, in the format of `\"path, index\"` where index is which icon in that file to use (See [WshShortcut.IconLocation](https://msdn.microsoft.com/en-us/library/3s9bx7at.aspx))\n\n#### Examples\n\nAdd a shortcut all users desktop:\n\n```ruby\nrequire 'win32ole'\nall_users_desktop = WIN32OLE.new(\"WScript.Shell\").SpecialFolders(\"AllUsersDesktop\")\n\nwindows_shortcut \"#{all_users_desktop}/Notepad.lnk\" do\n target \"C:\\\\WINDOWS\\\\notepad.exe\"\n description \"Launch Notepad\"\n iconlocation \"C:\\\\windows\\\\notepad.exe, 0\"\nend\n```\n\n#### Library Methods\n\n```ruby\nRegistry.value_exists?('HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run','BGINFO')\nRegistry.key_exists?('HKLM\\SOFTWARE\\Microsoft')\nBgInfo = Registry.get_value('HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run','BGINFO')\n```\n\n### windows_path\n\n#### Actions\n\n- `:add` - Add an item to the system path\n- `:remove` - Remove an item from the system path\n\n#### Properties\n\n- `path` - Name attribute. The name of the value to add to the system path\n\n#### Examples\n\nAdd Sysinternals to the system path\n\n```ruby\nwindows_path 'C:\\Sysinternals' do\n action :add\nend\n```\n\nRemove 7-Zip from the system path\n\n```ruby\nwindows_path 'C:\\7-Zip' do\n action :remove\nend\n```\n\n### windows_task\n\nCreates, deletes or runs a Windows scheduled task. Requires Windows Server 2008 due to API usage.\n\n#### Actions\n\n- `:create` - creates a task (or updates existing if user or command has changed)\n- `:delete` - deletes a task\n- `:run` - runs a task\n- `:end` - ends a task\n- `:change` - changes the un/pw or command of a task\n- `:enable` - enable a task\n- `:disable` - disable a task\n\n#### Properties\n\n- `task_name` - name attribute, The task name. (\"Task Name\" or \"/Task Name\")\n- `force` - When used with create, will update the task.\n- `command` - The command the task will run.\n- `cwd` - The directory the task will be run from.\n- `user` - The user to run the task as. (defaults to 'SYSTEM')\n- `password` - The user's password. (requires user)\n- `run_level` - Run with `:limited` or `:highest` privileges.\n- `frequency` - Frequency with which to run the task. (default is :hourly. Other valid values include :minute, :hourly, :daily, :weekly, :monthly, :once, :on_logon, :onstart, :on_idle) :once requires start_time\n- `frequency_modifier` - Multiple for frequency. (15 minutes, 2 days). Monthly tasks may also use these values\": ('FIRST', 'SECOND', 'THIRD', 'FOURTH', 'LAST', 'LASTDAY')\n- `start_day` - Specifies the first date on which the task runs. Optional string (MM/DD/YYYY)\n- `start_time` - Specifies the start time to run the task. Optional string (HH:mm)\n- `interactive_enabled` - (Allow task to run interactively or non-interactively. Requires user and password.)\n- `day` - For monthly or weekly tasks, the day(s) on which the task runs. (MON - SUN, *, 1 - 31)\n- `months` - The Months of the year on which the task runs. (JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC, *). Multiple months should be comma delimited.\n- `idle_time` - For :on_idle frequency, the time (in minutes) without user activity that must pass to trigger the task. (1 - 999)\n\n#### Examples\n\nCreate a `chef-client` task with TaskPath `\\` running every 15 minutes\n\n```ruby\nwindows_task 'chef-client' do\n user 'Administrator'\n password '$ecR3t'\n cwd 'C:\\\\chef\\\\bin'\n command 'chef-client -L C:\\\\tmp\\\\'\n run_level :highest\n frequency :minute\n frequency_modifier 15\nend\n```\n\nUpdate `chef-client` task with new password and log location\n\n```ruby\nwindows_task 'chef-client' do\n user 'Administrator'\n password 'N3wPassW0Rd'\n cwd 'C:\\\\chef\\\\bin'\n command 'chef-client -L C:\\\\chef\\\\logs\\\\'\n action :change\nend\n```\n\nDelete a task named `old task`\n\n```ruby\nwindows_task 'old task' do\n action :delete\nend\n```\n\nEnable a task named `chef-client`\n\n```ruby\nwindows_task 'chef-client' do\n action :enable\nend\n```\n\nDisable a task named `ProgramDataUpdater` with TaskPath `\\Microsoft\\Windows\\Application Experience\\`\n\n```ruby\nwindows_task '\\Microsoft\\Windows\\Application Experience\\ProgramDataUpdater' do\n action :disable\nend\n```\n\n### windows_zipfile\n\nMost version of Windows do not ship with native cli utility for managing compressed files. This resource provides a pure-ruby implementation for managing zip files. Be sure to use the `not_if` or `only_if` meta parameters to guard the resource for idempotence or action will be taken every Chef run.\n\n#### Actions\n\n- `:unzip` - unzip a compressed file\n- `:zip` - zip a directory (recursively)\n\n#### Properties\n\n- `path` - name attribute. The path where files will be (un)zipped to.\n- `source` - source of the zip file (either a URI or local path) for :unzip, or directory to be zipped for :zip.\n- `overwrite` - force an overwrite of the files if they already exist.\n- `checksum` - for :unzip, useful if source is remote, if the local file matches the SHA-256 checksum, Chef will not download it.\n\n#### Examples\n\nUnzip a remote zip file locally\n\n```ruby\nwindows_zipfile 'c:/bin' do\n source 'http://download.sysinternals.com/Files/SysinternalsSuite.zip'\n action :unzip\n not_if {::File.exists?('c:/bin/PsExec.exe')}\nend\n```\n\nUnzip a local zipfile\n\n```ruby\nwindows_zipfile 'c:/the_codez' do\n source 'c:/foo/baz/the_codez.zip'\n action :unzip\nend\n```\n\nCreate a local zipfile\n\n```ruby\nwindows_zipfile 'c:/foo/baz/the_codez.zip' do\n source 'c:/the_codez'\n action :zip\nend\n```\n\n## Libraries\n\n### WindowsHelper\n\nHelper that allows you to use helpful functions in windows\n\n#### installed_packages\n\nReturns a hash of all DisplayNames installed\n\n```ruby\n# usage in a recipe\n::Chef::Recipe.send(:include, Windows::Helper)\nhash_of_installed_packages = installed_packages\n```\n\n#### is_package_installed?\n\n- `package_name` - The name of the package you want to query to see if it is installed\n- `returns` - true if the package is installed, false if it the package is not installed\n\nDownload a file if a package isn't installed\n\n```ruby\n# usage in a recipe to not download a file if package is already installed\n::Chef::Recipe.send(:include, Windows::Helper)\nis_win_sdk_installed = is_package_installed?('Windows Software Development Kit')\n\nremote_file 'C:\\windows\\temp\\windows_sdk.zip' do\n source 'http://url_to_download/windows_sdk.zip'\n action :create_if_missing\n not_if {is_win_sdk_installed}\nend\n```\n\nDo something if a package is installed\n\n```ruby\n# usage in a provider\ninclude Windows::Helper\nif is_package_installed?('Windows Software Development Kit')\n # do something if package is installed\nend\n```\n\n### Windows::VersionHelper\n\nHelper that allows you to get information of the windows version running on your node. It leverages windows ohai from kernel.os_info, easy to mock and to use even on linux.\n\n#### core_version?\n\nDetermines whether given node is running on a windows Core.\n\n```ruby\nif ::Windows::VersionHelper.core_version? node\n fail 'Windows Core is not supported'\nend\n```\n\n#### workstation_version?\n\nDetermines whether given node is a windows workstation version (XP, Vista, 7, 8, 8.1, 10)\n\n```ruby\nif ::Windows::VersionHelper.workstation_version? node\n fail 'Only server version of windows are supported'\nend\n```\n\n#### server_version?\n\nDetermines whether given node is a windows server version (Server 2003, Server 2008, Server 2012, Server 2016)\n\n```ruby\nif ::Windows::VersionHelper.server_version? node\n puts 'Server version of windows are cool'\nend\n```\n\n#### nt_version\n\nDetermines NT version of the given node\n\n```ruby\ncase ::Windows::VersionHelper.nt_version node\n when '6.0' then 'Windows vista or Server 2008'\n when '6.1' then 'Windows 7 or Server 2008R2'\n when '6.2' then 'Windows 8 or Server 2012'\n when '6.3' then 'Windows 8.1 or Server 2012R2'\n when '10.0' then 'Windows 10'\nend\n```\n\n## Windows ChefSpec Matchers\n\nThe Windows cookbook includes custom [ChefSpec](https://github.com/sethvargo/chefspec) matchers you can use to test your own cookbooks that consume Windows cookbook LWRPs.\n\n### Example Matcher Usage\n\n```ruby\nexpect(chef_run).to install_windows_package('Node.js').with(\n source: 'http://nodejs.org/dist/v0.10.26/x64/node-v0.10.26-x64.msi')\n```\n\n### Windows Cookbook Matchers\n\n- create_windows_auto_run\n- remove_windows_auto_run\n- create_windows_certificate\n- delete_windows_certificate\n- add_acl_to_windows_certificate\n- create_windows_certificate_binding\n- delete_windows_certificate_binding\n- install_windows_feature\n- install_windows_feature_dism\n- install_windows_feature_servermanagercmd\n- install_windows_feature_powershell\n- remove_windows_feature\n- remove_windows_feature_dism\n- remove_windows_feature_servermanagercmd\n- remove_windows_feature_powershell\n- delete_windows_feature\n- delete_windows_feature_dism\n- delete_windows_feature_powershell\n- install_windows_font\n- create_windows_http_acl\n- delete_windows_http_acl\n- install_windows_package\n- remove_windows_package\n- set_windows_pagefile\n- add_windows_path\n- remove_windows_path\n- create_windows_printer\n- delete_windows_printer\n- create_windows_printer_port\n- delete_windows_printer_port\n- create_windows_shortcut\n- create_windows_shortcut\n- create_windows_task\n- disable_windows_task\n- enable_windows_task\n- delete_windows_task\n- run_windows_task\n- change_windows_task\n- unzip_windows_zipfile_to\n- zip_windows_zipfile_to\n\n## Usage\n\nPlace an explicit dependency on this cookbook (using depends in the cookbook's metadata.rb) from any cookbook where you would like to use the Windows-specific resources/providers that ship with this cookbook.\n\n```ruby\ndepends 'windows'\n```\n\n## License & Authors\n\n- Author:: Seth Chisamore ([schisamo@chef.io](mailto:schisamo@chef.io))\n- Author:: Doug MacEachern ([dougm@vmware.com](mailto:dougm@vmware.com))\n- Author:: Paul Morton ([pmorton@biaprotect.com](mailto:pmorton@biaprotect.com))\n- Author:: Doug Ireton ([doug.ireton@nordstrom.com](mailto:doug.ireton@nordstrom.com))\n\n```text\nCopyright 2011-2016, Chef Software, Inc.\nCopyright 2010, VMware, Inc.\nCopyright 2011, Business Intelligence Associates, Inc\nCopyright 2012, Nordstrom, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```\n","maintainer":"Chef Software, Inc.","maintainer_email":"cookbooks@chef.io","license":"Apache-2.0","platforms":{"windows":">= 0.0.0"},"dependencies":{"ohai":">= 4.0.0"},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{},"source_url":"https://github.com/chef-cookbooks/windows","issues_url":"https://github.com/chef-cookbooks/windows/issues","chef_version":[[">= 12.7"]],"ohai_version":[]} \ No newline at end of file diff --git a/cookbooks/windows/providers/auto_run.rb b/cookbooks/windows/providers/auto_run.rb deleted file mode 100644 index fad5e02..0000000 --- a/cookbooks/windows/providers/auto_run.rb +++ /dev/null @@ -1,33 +0,0 @@ -# -# Author:: Paul Morton () -# Cookbook Name:: windows -# Provider:: auto_run -# -# Copyright:: 2011, Business Intelligence Associates, Inc -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -use_inline_resources if defined?(use_inline_resources) - -action :create do - windows_registry 'HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run' do - values new_resource.name => "\"#{new_resource.program}\" #{new_resource.args}" - end -end - -action :remove do - windows_registry 'HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run' do - values new_resource.name => '' - action :remove - end -end diff --git a/cookbooks/windows/providers/batch.rb b/cookbooks/windows/providers/batch.rb deleted file mode 100644 index 6e5ffef..0000000 --- a/cookbooks/windows/providers/batch.rb +++ /dev/null @@ -1,64 +0,0 @@ -# -# Author:: Seth Chisamore () -# Cookbook Name:: windws -# Provider:: batch -# -# Copyright:: 2011-2015, Chef Software, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -use_inline_resources if defined?(use_inline_resources) - -require 'tempfile' -require 'chef/resource/execute' - -action :run do - begin - script_file.puts(@new_resource.code) - script_file.close - set_owner_and_group - - # cwd hax...shell_out on windows needs to support proper 'cwd' - # follow CHEF-2357 for more - cwd = @new_resource.cwd ? "cd \"#{@new_resource.cwd}\" & " : '' - - r = Chef::Resource::Execute.new(@new_resource.name, run_context) - r.user(@new_resource.user) - r.group(@new_resource.group) - r.command("#{cwd}call \"#{script_file.path}\" #{@new_resource.flags}") - r.creates(@new_resource.creates) - r.returns(@new_resource.returns) - r.run_action(:run) - - @new_resource.updated_by_last_action(r.updated_by_last_action?) - ensure - unlink_script_file - end -end - -private - -def set_owner_and_group - # FileUtils itself implements a no-op if +user+ or +group+ are nil - # You can prove this by running FileUtils.chown(nil,nil,'/tmp/file') - # as an unprivileged user. - FileUtils.chown(@new_resource.user, @new_resource.group, script_file.path) -end - -def script_file - @script_file ||= Tempfile.open(['chef-script', '.bat']) -end - -def unlink_script_file - @script_file && @script_file.close! -end diff --git a/cookbooks/windows/providers/certificate.rb b/cookbooks/windows/providers/certificate.rb deleted file mode 100644 index 5730b56..0000000 --- a/cookbooks/windows/providers/certificate.rb +++ /dev/null @@ -1,178 +0,0 @@ -# -# Author:: Richard Lavey (richard.lavey@calastone.com) -# Cookbook Name:: windows -# Provider:: certificate -# -# Copyright:: 2015, Calastone Ltd. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# See this for info on certutil -# https://technet.microsoft.com/en-gb/library/cc732443.aspx - -include Windows::Helper - -# Support whyrun -def whyrun_supported? - true -end - -use_inline_resources - -action :create do - hash = '$cert.GetCertHashString()' - code_script = cert_script(true) << - within_store_script { |store| store + '.Add($cert)' } << - acl_script(hash) - - guard_script = cert_script(false) << - cert_exists_script(hash) - - powershell_script @new_resource.name do - guard_interpreter :powershell_script - convert_boolean_return true - code code_script - not_if guard_script - end -end - -# acl_add is a modify-if-exists operation : not idempotent -action :acl_add do - if ::File.exist?(@new_resource.source) - hash = '$cert.GetCertHashString()' - code_script = cert_script(false) - guard_script = cert_script(false) - else - # make sure we have no spaces in the hash string - hash = "\"#{@new_resource.source.gsub(/\s/, '')}\"" - code_script = '' - guard_script = '' - end - code_script << acl_script(hash) - guard_script << cert_exists_script(hash) - - powershell_script @new_resource.name do - guard_interpreter :powershell_script - convert_boolean_return true - code code_script - only_if guard_script - end -end - -action :delete do - # do we have a hash or a subject? - # TODO: It's a bit annoying to know the thumbprint of a cert you want to remove when you already - # have the file. Support reading the hash directly from the file if provided. - if @new_resource.source.match(/^[a-fA-F0-9]{40}$/) - search = "Thumbprint -eq '#{@new_resource.source}'" - else - search = "Subject -like '*#{@new_resource.source.sub(/\*/, '`*')}*'" # escape any * in the source - end - cert_command = "Get-ChildItem Cert:\\#{@location}\\#{@new_resource.store_name} | where { $_.#{search} }" - - code_script = within_store_script do |store| - <<-EOH -foreach ($c in #{cert_command}) -{ - #{store}.Remove($c) -} -EOH - end - guard_script = "@(#{cert_command}).Count -gt 0\n" - - powershell_script @new_resource.name do - guard_interpreter :powershell_script - convert_boolean_return true - code code_script - only_if guard_script - end -end - -def load_current_resource - # Currently we don't read out the cert acl here and converge it in a very Chef-y way. - # We also don't read if the private key is available or populate "exists". This means - # that if you converged a cert without persisting the private key once, we won't do it - # again, even if you have a cert with the keys now. - # TODO: Make this more Chef-y and follow a more state-based patten of convergence. - @current_resource = Chef::Resource::WindowsCertificate.new(@new_resource.name) - # TODO: Change to allow source to be read from the cookbook. It makes testing - # and loading certs from the cookbook much easier. - @current_resource.source(@new_resource.source) - @current_resource.pfx_password(@new_resource.pfx_password) - @current_resource.private_key_acl(@new_resource.private_key_acl) - @current_resource.store_name(@new_resource.store_name) - @current_resource.user_store(@new_resource.user_store) - @location = @current_resource.user_store ? 'CurrentUser' : 'LocalMachine' -end - -private - -def cert_script(persist) - cert_script = '$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2' - file = win_friendly_path(@new_resource.source) - cert_script << " \"#{file}\"" - if ::File.extname(file.downcase) == '.pfx' - cert_script << ", \"#{@new_resource.pfx_password}\"" - if persist && @new_resource.user_store - cert_script << ', [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::PersistKeySet' - elsif persist - cert_script << ', ([System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::PersistKeySet -bor [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::MachineKeyset)' - end - end - cert_script << "\n" -end - -def cert_exists_script(hash) - <<-EOH -$hash = #{hash} -Test-Path "Cert:\\#{@location}\\#{@new_resource.store_name}\\$hash" -EOH -end - -def within_store_script - inner_script = yield '$store' - <<-EOH -$store = New-Object System.Security.Cryptography.X509Certificates.X509Store "#{@new_resource.store_name}", ([System.Security.Cryptography.X509Certificates.StoreLocation]::#{@location}) -$store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite) -#{inner_script} -$store.Close() -EOH -end - -def acl_script(hash) - return '' if @new_resource.private_key_acl.nil? || @new_resource.private_key_acl.length == 0 - # this PS came from http://blogs.technet.com/b/operationsguy/archive/2010/11/29/provide-access-to-private-keys-commandline-vs-powershell.aspx - # and from https://msdn.microsoft.com/en-us/library/windows/desktop/bb204778(v=vs.85).aspx - set_acl_script = <<-EOH -$hash = #{hash} -$storeCert = Get-ChildItem "cert:\\#{@location}\\#{@new_resource.store_name}\\$hash" -if ($storeCert -eq $null) { throw 'no key exists.' } -$keyname = $storeCert.PrivateKey.CspKeyContainerInfo.UniqueKeyContainerName -if ($keyname -eq $null) { throw 'no private key exists.' } -if ($storeCert.PrivateKey.CspKeyContainerInfo.MachineKeyStore) -{ -$fullpath = "$Env:ProgramData\\Microsoft\\Crypto\\RSA\\MachineKeys\\$keyname" -} -else -{ -$currentUser = New-Object System.Security.Principal.NTAccount($Env:UserDomain, $Env:UserName) -$userSID = $currentUser.Translate([System.Security.Principal.SecurityIdentifier]).Value -$fullpath = "$Env:ProgramData\\Microsoft\\Crypto\\RSA\\$userSID\\$keyname" -} -EOH - @new_resource.private_key_acl.each do |name| - set_acl_script << "$uname='#{name}'; icacls $fullpath /grant $uname`:RX\n" - end - set_acl_script -end diff --git a/cookbooks/windows/providers/certificate_binding.rb b/cookbooks/windows/providers/certificate_binding.rb deleted file mode 100644 index 341ab4e..0000000 --- a/cookbooks/windows/providers/certificate_binding.rb +++ /dev/null @@ -1,133 +0,0 @@ -# -# Author:: Richard Lavey (richard.lavey@calastone.com) -# Cookbook Name:: windows -# Provider:: certificate_binding -# -# Copyright:: 2015, Calastone Ltd. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# See https://msdn.microsoft.com/en-us/library/windows/desktop/cc307236%28v=vs.85%29.aspx for netsh info - -include Chef::Mixin::ShellOut -include Chef::Mixin::PowershellOut -include Windows::Helper - -# Support whyrun -def whyrun_supported? - true -end - -action :create do - hash = @new_resource.name_kind == :subject ? getHashFromSubject : @new_resource.cert_name - - if @current_resource.exists - needsChange = (hash.casecmp(@current_hash) != 0) - - if needsChange - converge_by("Changing #{@current_resource.address}:#{@current_resource.port}") do - deleteBinding - setBinding hash - end - else - Chef::Log.debug("#{@current_resource.address}:#{@current_resource.port} already bound to #{hash} - nothing to do") - end - else - converge_by("Binding #{@current_resource.address}:#{@current_resource.port}") do - setBinding hash - end - end -end - -action :delete do - if @current_resource.exists - converge_by("Deleting #{@current_resource.address}:#{@current_resource.port}") do - deleteBinding - end - else - Chef::Log.debug("#{@current_resource.address}:#{@current_resource.port} not bound - nothing to do") - end -end - -def load_current_resource - @current_resource = Chef::Resource::WindowsCertificateBinding.new(@new_resource.name) - @current_resource.cert_name(@new_resource.cert_name) - @current_resource.name_kind(@new_resource.name_kind) - @current_resource.address(@new_resource.address) - @current_resource.port(@new_resource.port) - @current_resource.store_name(@new_resource.store_name) - - @command = locate_sysnative_cmd('netsh.exe') - getCurrentHash -end - -private - -def getCurrentHash - cmd = shell_out("#{@command} http show sslcert ipport=#{@current_resource.address}:#{@current_resource.port}") - Chef::Log.debug "netsh reports: #{cmd.stdout}" - - if cmd.exitstatus == 0 - m = cmd.stdout.scan(/Certificate Hash\s+:\s?([A-Fa-f0-9]{40})/) - if m.length == 0 - fail "Failed to extract hash from command output #{cmd.stdout}" - else - @current_hash = m[0][0] - @current_resource.exists = true - end - else - @current_resource.exists = false - end -end - -def setBinding(hash) - cmd = "#{@command} http add sslcert" - cmd << " ipport=#{@current_resource.address}:#{@current_resource.port}" - cmd << " certhash=#{hash}" - cmd << " appid=#{@current_resource.app_id}" - cmd << " certstorename=#{@current_resource.store_name}" - checkHash hash - - shell_out!(cmd) -end - -def deleteBinding - shell_out!("#{@command} http delete sslcert ipport=#{@current_resource.address}:#{@current_resource.port}") -end - -def checkHash(hash) - p = powershell_out!("Test-Path \"cert:\\LocalMachine\\#{@current_resource.store_name}\\#{hash}\"") - - unless p.stderr.empty? && p.stdout =~ /True/i - fail "A Cert with hash of #{hash} doesn't exist in keystore LocalMachine\\#{@current_resource.store_name}" - end - nil -end - -def getHashFromSubject - # escape wildcard subject name (*.acme.com) - subject = @current_resource.cert_name.sub(/\*/, '`*') - ps_script = "& { gci cert:\\localmachine\\#{@current_resource.store_name} | where subject -like '*#{subject}*' | select -first 1 -expandproperty Thumbprint }" - - Chef::Log.debug "Running PS script #{ps_script}" - p = powershell_out!(ps_script) - - if !p.stderr.nil? && p.stderr.length > 0 - fail "#{ps_script} failed with #{p.stderr}" - elsif p.stdout.nil? || p.stdout.length == 0 - fail "Couldn't find thumbprint for subject #{@current_resource.cert_name}" - end - - p.stdout.strip -end diff --git a/cookbooks/windows/providers/feature_dism.rb b/cookbooks/windows/providers/feature_dism.rb deleted file mode 100644 index a0c1cb6..0000000 --- a/cookbooks/windows/providers/feature_dism.rb +++ /dev/null @@ -1,65 +0,0 @@ -# -# Author:: Seth Chisamore () -# Cookbook Name:: windows -# Provider:: feature_dism -# -# Copyright:: 2011-2015, Chef Software, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -include Chef::Provider::WindowsFeature::Base -include Chef::Mixin::ShellOut -include Windows::Helper - -def install_feature(_name) - addsource = @new_resource.source ? "/LimitAccess /Source:\"#{@new_resource.source}\"" : '' - addall = @new_resource.all ? '/All' : '' - shell_out!("#{dism} /online /enable-feature /featurename:#{@new_resource.feature_name} /norestart #{addsource} #{addall}", returns: [0, 42, 127, 3010]) -end - -def remove_feature(_name) - shell_out!("#{dism} /online /disable-feature /featurename:#{@new_resource.feature_name} /norestart", returns: [0, 42, 127, 3010]) -end - -def delete_feature(_name) - if win_version.major_version >= 6 && win_version.minor_version >= 2 - shell_out!("#{dism} /online /disable-feature /featurename:#{@new_resource.feature_name} /Remove /norestart", returns: [0, 42, 127, 3010]) - else - fail Chef::Exceptions::UnsupportedAction, "#{self} :delete action not support on #{win_version.sku}" - end -end - -def installed? - @installed ||= begin - cmd = shell_out("#{dism} /online /Get-Features", returns: [0, 42, 127]) - cmd.stderr.empty? && (cmd.stdout =~ /^Feature Name : #{@new_resource.feature_name}.?$\n^State : Enabled.?$/i) - end -end - -def available? - @available ||= begin - cmd = shell_out("#{dism} /online /Get-Features", returns: [0, 42, 127]) - cmd.stderr.empty? && (cmd.stdout !~ /^Feature Name : #{@new_resource.feature_name}.?$\n^State : .* with payload removed.?$/i) - end -end - -private - -# account for File System Redirector -# http://msdn.microsoft.com/en-us/library/aa384187(v=vs.85).aspx -def dism - @dism ||= begin - locate_sysnative_cmd('dism.exe') - end -end diff --git a/cookbooks/windows/providers/feature_powershell.rb b/cookbooks/windows/providers/feature_powershell.rb deleted file mode 100644 index e7cd867..0000000 --- a/cookbooks/windows/providers/feature_powershell.rb +++ /dev/null @@ -1,38 +0,0 @@ -# -# Author:: Greg Zapp () -# Cookbook Name:: windows -# Provider:: feature_powershell -# - -include Chef::Provider::WindowsFeature::Base -include Chef::Mixin::PowershellOut -include Windows::Helper - -def install_feature(_name) - cmd = powershell_out("Install-WindowsFeature #{@new_resource.feature_name}") - Chef::Log.info(cmd.stdout) -end - -def remove_feature(_name) - cmd = powershell_out("Uninstall-WindowsFeature #{@new_resource.feature_name}") - Chef::Log.info(cmd.stdout) -end - -def delete_feature(_name) - cmd = powershell_out("Uninstall-WindowsFeature #{@new_resource.feature_name} -Remove") - Chef::Log.info(cmd.stdout) -end - -def installed? - @installed ||= begin - cmd = powershell_out("Get-WindowsFeature #{@new_resource.feature_name} | Select Installed | % { Write-Host $_.Installed }") - cmd.stderr.empty? && cmd.stdout =~ /True/i - end -end - -def available? - @available ||= begin - cmd = powershell_out("Get-WindowsFeature #{@new_resource.feature_name}") - cmd.stderr.empty? && cmd.stdout !~ /Removed/i - end -end diff --git a/cookbooks/windows/providers/feature_servermanagercmd.rb b/cookbooks/windows/providers/feature_servermanagercmd.rb deleted file mode 100644 index 75e25c2..0000000 --- a/cookbooks/windows/providers/feature_servermanagercmd.rb +++ /dev/null @@ -1,61 +0,0 @@ -# -# Author:: Seth Chisamore () -# Cookbook Name:: windows -# Provider:: feature_servermanagercmd -# -# Copyright:: 2011-2015, Chef Software, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -include Chef::Provider::WindowsFeature::Base -include Chef::Mixin::ShellOut -include Windows::Helper - -# Exit codes are listed at http://technet.microsoft.com/en-us/library/cc749128(v=ws.10).aspx - -def check_reboot(result, feature) - if result.exitstatus == 3010 # successful, but needs reboot - node.run_state[:reboot_requested] = true - Chef::Log.warn("Require reboot to install #{feature}") - elsif result.exitstatus == 1001 # failure, but needs reboot before we can do anything else - node.run_state[:reboot_requested] = true - Chef::Log.warn("Failed installing #{feature} and need to reboot") - end - result.error! # throw for any other bad results. The above results will also get raised, and should cause a reboot via the handler. -end - -def install_feature(_name) - check_reboot(shell_out("#{servermanagercmd} -install #{@new_resource.feature_name}", returns: [0, 42, 127, 1003, 3010]), @new_resource.feature_name) -end - -def remove_feature(_name) - check_reboot(shell_out("#{servermanagercmd} -remove #{@new_resource.feature_name}", returns: [0, 42, 127, 1003, 3010]), @new_resource.feature_name) -end - -def installed? - @installed ||= begin - cmd = shell_out("#{servermanagercmd} -query", returns: [0, 42, 127, 1003]) - cmd.stderr.empty? && (cmd.stdout =~ /^\s*?\[X\]\s.+?\s\[#{@new_resource.feature_name}\]\s*$/i) - end -end - -private - -# account for File System Redirector -# http://msdn.microsoft.com/en-us/library/aa384187(v=vs.85).aspx -def servermanagercmd - @servermanagercmd ||= begin - locate_sysnative_cmd('servermanagercmd.exe') - end -end diff --git a/cookbooks/windows/providers/font.rb b/cookbooks/windows/providers/font.rb deleted file mode 100644 index e185062..0000000 --- a/cookbooks/windows/providers/font.rb +++ /dev/null @@ -1,69 +0,0 @@ -# -# Author:: Sander Botman -# Cookbook Name:: windows -# Provider:: font -# -# Copyright:: 2014, Schuberg Philis BV. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -include Windows::Helper - -def load_current_resource - require 'win32ole' - fonts_dir = WIN32OLE.new('WScript.Shell').SpecialFolders('Fonts') - @current_resource = Chef::Resource::WindowsFont.new(@new_resource.name) - @current_resource.file(win_friendly_path(::File.join(fonts_dir, @new_resource.file))) - @current_resource -end - -# Check to see if the font is installed -# -# === Returns -# :: If the font is installed -# :: If the font is not instaled -def font_exists? - ::File.exist?(@current_resource.file) -end - -def get_cookbook_font - r = Chef::Resource::CookbookFile.new(@new_resource.file, run_context) - r.path(win_friendly_path(::File.join(ENV['TEMP'], @new_resource.file))) - r.cookbook(cookbook_name.to_s) - r.run_action(:create) -end - -def del_cookbook_font - r = Chef::Resource::File.new(::File.join(ENV['TEMP'], @new_resource.file), run_context) - r.run_action(:delete) -end - -def install_font - require 'win32ole' - fonts_dir = WIN32OLE.new('WScript.Shell').SpecialFolders('Fonts') - folder = WIN32OLE.new('Shell.Application').Namespace(fonts_dir) - folder.CopyHere(win_friendly_path(::File.join(ENV['TEMP'], @new_resource.file))) - Chef::Log.debug("Installing font: #{@new_resource.file}") -end - -def action_install - unless font_exists? - get_cookbook_font - install_font - del_cookbook_font - new_resource.updated_by_last_action(true) - else - Chef::Log.debug("Not installing font: #{@new_resource.file}, font already installed.") - new_resource.updated_by_last_action(false) - end -end diff --git a/cookbooks/windows/providers/http_acl.rb b/cookbooks/windows/providers/http_acl.rb deleted file mode 100644 index 6487bab..0000000 --- a/cookbooks/windows/providers/http_acl.rb +++ /dev/null @@ -1,91 +0,0 @@ -# -# Author:: Richard Lavey (richard.lavey@calastone.com) -# Cookbook Name:: windows -# Provider:: http_acl -# -# Copyright:: 2015, Calastone Ltd. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# See https://msdn.microsoft.com/en-us/library/windows/desktop/cc307236%28v=vs.85%29.aspx for netsh info - -include Chef::Mixin::ShellOut -include Windows::Helper - -# Support whyrun -def whyrun_supported? - true -end - -action :create do - fail 'No user property set' if @new_resource.user.nil? || @new_resource.user.empty? - - if @current_resource.exists - needsChange = (@current_resource.user.casecmp(@new_resource.user) != 0) - - if needsChange - converge_by("Changing #{@current_resource.url}") do - deleteAcl - setAcl - end - else - Chef::Log.debug("#{@current_resource.url} already set - nothing to do") - end - else - converge_by("Setting #{@current_resource.url}") do - setAcl - end - end -end - -action :delete do - if @current_resource.exists - converge_by("Deleting #{@current_resource.url}") do - deleteAcl - end - else - Chef::Log.debug("#{@current_resource.url} does not exist - nothing to do") - end -end - -def load_current_resource - @current_resource = Chef::Resource::WindowsHttpAcl.new(@new_resource.name) - @current_resource.url(@new_resource.url) - - @command = locate_sysnative_cmd('netsh.exe') - getCurrentAcl -end - -private - -def getCurrentAcl - cmd = shell_out!("#{@command} http show urlacl url=#{@current_resource.url}") - Chef::Log.debug "netsh reports: #{cmd.stdout}" - - m = cmd.stdout.scan(/User:\s*(\S+)/) - if m.length == 0 - @current_resource.exists = false - else - @current_resource.user(m[0][0]) - @current_resource.exists = true - end -end - -def setAcl - shell_out!("#{@command} http add urlacl url=#{@new_resource.url} user=\"#{@new_resource.user}\"") -end - -def deleteAcl - shell_out!("#{@command} http delete urlacl url=#{@new_resource.url}") -end diff --git a/cookbooks/windows/providers/pagefile.rb b/cookbooks/windows/providers/pagefile.rb deleted file mode 100644 index a83ba0b..0000000 --- a/cookbooks/windows/providers/pagefile.rb +++ /dev/null @@ -1,149 +0,0 @@ -# -# Author:: Kevin Moser () -# Cookbook Name:: windows -# Provider:: pagefile -# -# Copyright:: 2012, Nordstrom, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -include Chef::Mixin::ShellOut -include Windows::Helper - -action :set do - pagefile = @new_resource.name - initial_size = @new_resource.initial_size - maximum_size = @new_resource.maximum_size - system_managed = @new_resource.system_managed - automatic_managed = @new_resource.automatic_managed - updated = false - - if automatic_managed - unless automatic_managed? - set_automatic_managed - updated = true - end - else - if automatic_managed? - unset_automatic_managed - updated = true - end - - # Check that the resource is not just trying to unset automatic managed, if it is do nothing more - if (initial_size && maximum_size) || system_managed - create(pagefile) unless exists?(pagefile) - - if system_managed - unless max_and_min_set?(pagefile, 0, 0) - set_system_managed(pagefile) - updated = true - end - else - unless max_and_min_set?(pagefile, initial_size, maximum_size) - set_custom_size(pagefile, initial_size, maximum_size) - updated = true - end - end - end - end - - new_resource.updated_by_last_action(updated) -end - -action :delete do - pagefile = @new_resource.name - updated = false - - if exists?(pagefile) - delete(pagefile) - updated = true - end - - new_resource.updated_by_last_action(updated) -end - -private - -def exists?(pagefile) - @exists ||= begin - cmd = shell_out("#{wmic} pagefileset where SettingID=\"#{get_setting_id(pagefile)}\" list /format:list", returns: [0]) - cmd.stderr.empty? && (cmd.stdout =~ /SettingID=#{get_setting_id(pagefile)}/i) - end -end - -def max_and_min_set?(pagefile, min, max) - @max_and_min_set ||= begin - cmd = shell_out("#{wmic} pagefileset where SettingID=\"#{get_setting_id(pagefile)}\" list /format:list", returns: [0]) - cmd.stderr.empty? && (cmd.stdout =~ /InitialSize=#{min}/i) && (cmd.stdout =~ /MaximumSize=#{max}/i) - end -end - -def create(pagefile) - Chef::Log.debug("Creating pagefile #{pagefile}") - cmd = shell_out("#{wmic} pagefileset create name=\"#{win_friendly_path(pagefile)}\"") - check_for_errors(cmd.stderr) -end - -def delete(pagefile) - Chef::Log.debug("Removing pagefile #{pagefile}") - cmd = shell_out("#{wmic} pagefileset where SettingID=\"#{get_setting_id(pagefile)}\" delete") - check_for_errors(cmd.stderr) -end - -def automatic_managed? - @automatic_managed ||= begin - cmd = shell_out("#{wmic} computersystem where name=\"%computername%\" get AutomaticManagedPagefile /format:list") - cmd.stderr.empty? && (cmd.stdout =~ /AutomaticManagedPagefile=TRUE/i) - end -end - -def set_automatic_managed - Chef::Log.debug('Setting pagefile to Automatic Managed') - cmd = shell_out("#{wmic} computersystem where name=\"%computername%\" set AutomaticManagedPagefile=True") - check_for_errors(cmd.stderr) -end - -def unset_automatic_managed - Chef::Log.debug('Setting pagefile to User Managed') - cmd = shell_out("#{wmic} computersystem where name=\"%computername%\" set AutomaticManagedPagefile=False") - check_for_errors(cmd.stderr) -end - -def set_custom_size(pagefile, min, max) - Chef::Log.debug("Setting #{pagefile} to InitialSize=#{min} & MaximumSize=#{max}") - cmd = shell_out("#{wmic} pagefileset where SettingID=\"#{get_setting_id(pagefile)}\" set InitialSize=#{min},MaximumSize=#{max}", returns: [0]) - check_for_errors(cmd.stderr) -end - -def set_system_managed(pagefile) - Chef::Log.debug("Setting #{pagefile} to System Managed") - cmd = shell_out("#{wmic} pagefileset where SettingID=\"#{get_setting_id(pagefile)}\" set InitialSize=0,MaximumSize=0", returns: [0]) - check_for_errors(cmd.stderr) -end - -def get_setting_id(pagefile) - pagefile = win_friendly_path(pagefile) - pagefile = pagefile.split('\\') - "#{pagefile[1]} @ #{pagefile[0]}" -end - -def check_for_errors(stderr) - Chef::Log.fatal(stderr) unless stderr.empty? -end - -def wmic - @wmic ||= begin - locate_sysnative_cmd('wmic.exe') - end -end diff --git a/cookbooks/windows/providers/path.rb b/cookbooks/windows/providers/path.rb deleted file mode 100644 index f246dd7..0000000 --- a/cookbooks/windows/providers/path.rb +++ /dev/null @@ -1,52 +0,0 @@ -# -# Author:: Paul Morton () -# Cookbook Name:: windows -# Provider:: path -# -# Copyright:: 2011, Business Intelligence Associates, Inc -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -use_inline_resources if defined?(use_inline_resources) - -include Windows::Helper - -action :add do - env 'path' do - action :modify - delim ::File::PATH_SEPARATOR - value new_resource.path - notifies :run, "ruby_block[fix ruby ENV['PATH']]", :immediately - end - - # The windows Env provider does not correctly expand variables in - # the PATH environment variable. Ruby expects these to be expanded. - # This is a temporary fix for that. - # - # Follow at https://github.com/chef/chef/pull/1876 - # - ruby_block "fix ruby ENV['PATH']" do - block do - ENV['PATH'] = expand_env_vars(ENV['PATH']) - end - action :nothing - end -end - -action :remove do - env 'path' do - action :delete - delim ::File::PATH_SEPARATOR - value new_resource.path - end -end diff --git a/cookbooks/windows/providers/printer.rb b/cookbooks/windows/providers/printer.rb deleted file mode 100644 index 5da6730..0000000 --- a/cookbooks/windows/providers/printer.rb +++ /dev/null @@ -1,99 +0,0 @@ -# -# Author:: Doug Ireton () -# Cookbook Name:: windows -# Provider:: printer -# -# Copyright:: 2012, Nordstrom, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -use_inline_resources if defined?(use_inline_resources) - -# Support whyrun -def whyrun_supported? - true -end - -action :create do - if @current_resource.exists - Chef::Log.info "#{@new_resource} already exists - nothing to do." - else - converge_by("Create #{@new_resource}") do - create_printer - end - end -end - -action :delete do - if @current_resource.exists - converge_by("Delete #{@new_resource}") do - delete_printer - end - else - Chef::Log.info "#{@current_resource} doesn't exist - can't delete." - end -end - -def load_current_resource - @current_resource = Chef::Resource::WindowsPrinter.new(@new_resource.name) - @current_resource.name(@new_resource.name) - - if printer_exists?(@current_resource.name) - # TODO: Set @current_resource printer properties from registry - @current_resource.exists = true - end -end - -private - -PRINTERS_REG_KEY = 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Printers\\'.freeze unless defined?(PRINTERS_REG_KEY) - -def printer_exists?(name) - printer_reg_key = PRINTERS_REG_KEY + name - Chef::Log.debug "Checking to see if this reg key exists: '#{printer_reg_key}'" - Registry.key_exists?(printer_reg_key) -end - -def create_printer - # Create the printer port first - windows_printer_port new_resource.ipv4_address do - end - - port_name = "IP_#{new_resource.ipv4_address}" - - powershell_script "Creating printer: #{new_resource.name}" do - code <<-EOH - - Set-WmiInstance -class Win32_Printer ` - -EnableAllPrivileges ` - -Argument @{ DeviceID = "#{new_resource.device_id}"; - Comment = "#{new_resource.comment}"; - Default = "$#{new_resource.default}"; - DriverName = "#{new_resource.driver_name}"; - Location = "#{new_resource.location}"; - PortName = "#{port_name}"; - Shared = "$#{new_resource.shared}"; - ShareName = "#{new_resource.share_name}"; - } - EOH - end -end - -def delete_printer - powershell_script "Deleting printer: #{new_resource.name}" do - code <<-EOH - $printer = Get-WMIObject -class Win32_Printer -EnableAllPrivileges -Filter "name = '#{new_resource.name}'" - $printer.Delete() - EOH - end -end diff --git a/cookbooks/windows/providers/printer_port.rb b/cookbooks/windows/providers/printer_port.rb deleted file mode 100644 index 1793291..0000000 --- a/cookbooks/windows/providers/printer_port.rb +++ /dev/null @@ -1,99 +0,0 @@ -# -# Author:: Doug Ireton () -# Cookbook Name:: windows -# Provider:: printer_port -# -# Copyright:: 2012, Nordstrom, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -use_inline_resources if defined?(use_inline_resources) - -# Support whyrun -def whyrun_supported? - true -end - -action :create do - if @current_resource.exists - Chef::Log.info "#{@new_resource} already exists - nothing to do." - else - converge_by("Create #{@new_resource}") do - create_printer_port - end - end -end - -action :delete do - if @current_resource.exists - converge_by("Delete #{@new_resource}") do - delete_printer_port - end - else - Chef::Log.info "#{@current_resource} doesn't exist - can't delete." - end -end - -def load_current_resource - @current_resource = Chef::Resource::WindowsPrinterPort.new(@new_resource.name) - @current_resource.name(@new_resource.name) - @current_resource.ipv4_address(@new_resource.ipv4_address) - @current_resource.port_name(@new_resource.port_name || "IP_#{@new_resource.ipv4_address}") - - if port_exists?(@current_resource.port_name) - # TODO: Set @current_resource port properties from registry - @current_resource.exists = true - end -end - -private - -PORTS_REG_KEY = 'HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Print\Monitors\Standard TCP/IP Port\Ports\\'.freeze unless defined?(PORTS_REG_KEY) - -def port_exists?(name) - port_reg_key = PORTS_REG_KEY + name - - Chef::Log.debug "Checking to see if this reg key exists: '#{port_reg_key}'" - Registry.key_exists?(port_reg_key) -end - -def create_printer_port - port_name = new_resource.port_name || "IP_#{new_resource.ipv4_address}" - - # create the printer port using PowerShell - powershell_script "Creating printer port #{new_resource.port_name}" do - code <<-EOH - - Set-WmiInstance -class Win32_TCPIPPrinterPort ` - -EnableAllPrivileges ` - -Argument @{ HostAddress = "#{new_resource.ipv4_address}"; - Name = "#{port_name}"; - Description = "#{new_resource.port_description}"; - PortNumber = "#{new_resource.port_number}"; - Protocol = "#{new_resource.port_protocol}"; - SNMPEnabled = "$#{new_resource.snmp_enabled}"; - } - EOH - end -end - -def delete_printer_port - port_name = new_resource.port_name || "IP_#{new_resource.ipv4_address}" - - powershell_script "Deleting printer port: #{new_resource.port_name}" do - code <<-EOH - $port = Get-WMIObject -class Win32_TCPIPPrinterPort -EnableAllPrivileges -Filter "name = '#{port_name}'" - $port.Delete() - EOH - end -end diff --git a/cookbooks/windows/providers/reboot.rb b/cookbooks/windows/providers/reboot.rb deleted file mode 100644 index 5da1903..0000000 --- a/cookbooks/windows/providers/reboot.rb +++ /dev/null @@ -1,33 +0,0 @@ -# -# Author:: Seth Chisamore () -# Cookbook Name:: windows -# Provider:: reboot -# -# Copyright:: 2011-2015, Chef Software, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -action :request do - node.run_state[:reboot_requested] = true - node.run_state[:reboot_timeout] = @new_resource.timeout - node.run_state[:reboot_reason] = @new_resource.reason - new_resource.updated_by_last_action(true) -end - -action :cancel do - node.run_state.delete(:reboot_requested) - node.run_state.delete(:reboot_timeout) - node.run_state.delete(:reboot_reason) - new_resource.updated_by_last_action(true) -end diff --git a/cookbooks/windows/providers/registry.rb b/cookbooks/windows/providers/registry.rb deleted file mode 100644 index 71637c8..0000000 --- a/cookbooks/windows/providers/registry.rb +++ /dev/null @@ -1,75 +0,0 @@ -# -# Author:: Doug MacEachern () -# Author:: Seth Chisamore () -# Author:: Paul Morton () -# Cookbook Name:: windows -# Provider:: registry -# -# Copyright:: 2010, VMware, Inc. -# Copyright:: 2011-2015, Chef Software, Inc. -# Copyright:: 2011, Business Intelligence Associates, Inc -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -include Windows::RegistryHelper - -action :create do - updated = registry_update(:create) - new_resource.updated_by_last_action(updated) -end - -action :modify do - updated = registry_update(:open) - new_resource.updated_by_last_action(updated) -end - -action :force_modify do - require 'timeout' - Timeout.timeout(120) do - @new_resource.values.each do |value_name, value_data| - i = 1 - until i > 5 - desired_value_data = value_data - current_value_data = get_value(@new_resource.key_name.dup, value_name.dup) - if current_value_data.to_s == desired_value_data.to_s - Chef::Log.debug("#{@new_resource} value [#{value_name}] desired [#{desired_value_data}] data already set. Check #{i}/5.") - i += 1 - else - Chef::Log.debug("#{@new_resource} value [#{value_name}] current [#{current_value_data}] data not equal to desired [#{desired_value_data}] data. Setting value and restarting check loop.") - begin - updated = registry_update(:open) - new_resource.updated_by_last_action(updated) - rescue Exception - updated = registry_update(:create) - new_resource.updated_by_last_action(updated) - end - i = 0 # start count loop over - end - end - end - break - end -end - -action :remove do - delete_value(@new_resource.key_name, @new_resource.values) - new_resource.updated_by_last_action(true) -end - -private - -def registry_update(mode) - Chef::Log.debug("Registry Mode (#{mode})") - updated = set_value(mode, @new_resource.key_name, @new_resource.values, @new_resource.type) -end diff --git a/cookbooks/windows/providers/shortcut.rb b/cookbooks/windows/providers/shortcut.rb deleted file mode 100644 index 2b909b3..0000000 --- a/cookbooks/windows/providers/shortcut.rb +++ /dev/null @@ -1,58 +0,0 @@ -# -# Author:: Doug MacEachern -# Cookbook Name:: windows -# Provider:: shortcut -# -# Copyright:: 2010, VMware, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -def load_current_resource - require 'win32ole' - - @link = WIN32OLE.new('WScript.Shell').CreateShortcut(@new_resource.name) - - @current_resource = Chef::Resource::WindowsShortcut.new(@new_resource.name) - @current_resource.name(@new_resource.name) - @current_resource.target(@link.TargetPath) - @current_resource.arguments(@link.Arguments) - @current_resource.description(@link.Description) - @current_resource.cwd(@link.WorkingDirectory) - @current_resource.iconlocation(@link.IconLocation) -end - -# Check to see if the shorcut needs any changes -# -# === Returns -# :: If a change is required -# :: If the shorcuts are identical -def compare_shortcut - [:target, :arguments, :description, :cwd, :iconlocation].any? do |attr| - !@new_resource.send(attr).nil? && @current_resource.send(attr) != @new_resource.send(attr) - end -end - -def action_create - if compare_shortcut - @link.TargetPath = @new_resource.target unless @new_resource.target.nil? - @link.Arguments = @new_resource.arguments unless @new_resource.arguments.nil? - @link.Description = @new_resource.description unless @new_resource.description.nil? - @link.WorkingDirectory = @new_resource.cwd unless @new_resource.cwd.nil? - @link.IconLocation = @new_resource.iconlocation unless @new_resource.iconlocation.nil? - # ignoring: WindowStyle, Hotkey - @link.Save - Chef::Log.info("Added #{@new_resource} shortcut") - new_resource.updated_by_last_action(true) - end -end diff --git a/cookbooks/windows/providers/task.rb b/cookbooks/windows/providers/task.rb deleted file mode 100644 index 4ecaa1c..0000000 --- a/cookbooks/windows/providers/task.rb +++ /dev/null @@ -1,236 +0,0 @@ -# -# Author:: Paul Mooring () -# Cookbook Name:: windows -# Provider:: task -# -# Copyright:: 2012-2015, Chef Software, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -require 'chef/mixin/shell_out' -include Chef::Mixin::ShellOut - -use_inline_resources - -action :create do - if @current_resource.exists && (!(task_need_update? || @new_resource.force)) - Chef::Log.info "#{@new_resource} task already exists - nothing to do" - else - validate_user_and_password - validate_interactive_setting - validate_create_day - - schedule = @new_resource.frequency == :on_logon ? 'ONLOGON' : @new_resource.frequency - frequency_modifier_allowed = [:minute, :hourly, :daily, :weekly, :monthly] - options = {} - options['F'] = '' if @new_resource.force || task_need_update? - options['SC'] = schedule - options['MO'] = @new_resource.frequency_modifier if frequency_modifier_allowed.include?(@new_resource.frequency) - options['SD'] = @new_resource.start_day unless @new_resource.start_day.nil? - options['ST'] = @new_resource.start_time unless @new_resource.start_time.nil? - options['TR'] = "\"#{@new_resource.command}\" " - options['RU'] = @new_resource.user - options['RP'] = @new_resource.password if use_password? - options['RL'] = 'HIGHEST' if @new_resource.run_level == :highest - options['IT'] = '' if @new_resource.interactive_enabled - options['D'] = @new_resource.day if @new_resource.day - - run_schtasks 'CREATE', options - new_resource.updated_by_last_action true - Chef::Log.info "#{@new_resource} task created" - end -end - -action :run do - if @current_resource.exists - if @current_resource.status == :running - Chef::Log.info "#{@new_resource} task is currently running, skipping run" - else - run_schtasks 'RUN' - new_resource.updated_by_last_action true - Chef::Log.info "#{@new_resource} task ran" - end - else - Chef::Log.debug "#{@new_resource} task doesn't exists - nothing to do" - end -end - -action :change do - if @current_resource.exists - validate_user_and_password - validate_interactive_setting - - options = {} - options['TR'] = "\"#{@new_resource.command}\" " if @new_resource.command - options['RU'] = @new_resource.user if @new_resource.user - options['RP'] = @new_resource.password if @new_resource.password - options['SD'] = @new_resource.start_day unless @new_resource.start_day.nil? - options['ST'] = @new_resource.start_time unless @new_resource.start_time.nil? - options['IT'] = '' if @new_resource.interactive_enabled - - run_schtasks 'CHANGE', options - new_resource.updated_by_last_action true - Chef::Log.info "Change #{@new_resource} task ran" - else - Chef::Log.debug "#{@new_resource} task doesn't exists - nothing to do" - end -end - -action :delete do - if @current_resource.exists - # always need to force deletion - run_schtasks 'DELETE', 'F' => '' - new_resource.updated_by_last_action true - Chef::Log.info "#{@new_resource} task deleted" - else - Chef::Log.debug "#{@new_resource} task doesn't exists - nothing to do" - end -end - -action :end do - if @current_resource.exists - if @current_resource.status != :running - Chef::Log.debug "#{@new_resource} is not running - nothing to do" - else - run_schtasks 'END' - @new_resource.updated_by_last_action true - Chef::Log.info "#{@new_resource} task ended" - end - else - Chef::Log.fatal "#{@new_resource} task doesn't exist - nothing to do" - fail Errno::ENOENT, "#{@new_resource}: task does not exist, cannot end" - end -end - -action :enable do - if @current_resource.exists - if @current_resource.enabled - Chef::Log.debug "#{@new_resource} already enabled - nothing to do" - else - run_schtasks 'CHANGE', 'ENABLE' => '' - @new_resource.updated_by_last_action true - Chef::Log.info "#{@new_resource} task enabled" - end - else - Chef::Log.fatal "#{@new_resource} task doesn't exist - nothing to do" - fail Errno::ENOENT, "#{@new_resource}: task does not exist, cannot enable" - end -end - -action :disable do - if @current_resource.exists - if @current_resource.enabled - run_schtasks 'CHANGE', 'DISABLE' => '' - @new_resource.updated_by_last_action true - Chef::Log.info "#{@new_resource} task disabled" - else - Chef::Log.debug "#{@new_resource} already disabled - nothing to do" - end - else - Chef::Log.debug "#{@new_resource} task doesn't exist - nothing to do" - end -end - -def load_current_resource - @current_resource = Chef::Resource::WindowsTask.new(@new_resource.name) - @current_resource.task_name(@new_resource.task_name) - - pathed_task_name = @new_resource.task_name[0, 1] == '\\' ? @new_resource.task_name : @new_resource.task_name.prepend('\\') - task_hash = load_task_hash(@current_resource.task_name) - if task_hash[:TaskName] == pathed_task_name - @current_resource.exists = true - @current_resource.status = :running if task_hash[:Status] == 'Running' - if task_hash[:ScheduledTaskState] == 'Enabled' - @current_resource.enabled = true - end - @current_resource.cwd(task_hash[:Folder]) - @current_resource.command(task_hash[:TaskToRun]) - @current_resource.user(task_hash[:RunAsUser]) - end if task_hash.respond_to? :[] -end - -private - -def run_schtasks(task_action, options = {}) - cmd = "schtasks /#{task_action} /TN \"#{@new_resource.task_name}\" " - options.keys.each do |option| - cmd += "/#{option} #{options[option]} " - end - Chef::Log.debug('running: ') - Chef::Log.debug(" #{cmd}") - shell_out!(cmd, returns: [0]) -end - -def task_need_update? - # gsub needed as schtasks converts single quotes to double quotes on creation - @current_resource.command != @new_resource.command.tr("'", "\"") || - @current_resource.user != @new_resource.user -end - -def load_task_hash(task_name) - Chef::Log.debug 'looking for existing tasks' - - # we use shell_out here instead of shell_out! because a failure implies that the task does not exist - output = shell_out("schtasks /Query /FO LIST /V /TN \"#{task_name}\"").stdout - if output.empty? - task = false - else - task = {} - - output.split("\n").map! do |line| - line.split(':', 2).map!(&:strip) - end.each do |field| - if field.is_a?(Array) && field[0].respond_to?(:to_sym) - task[field[0].gsub(/\s+/, '').to_sym] = field[1] - end - end - end - - task -end - -SYSTEM_USERS = ['NT AUTHORITY\SYSTEM', 'SYSTEM', 'NT AUTHORITY\LOCALSERVICE', 'NT AUTHORITY\NETWORKSERVICE'] - -def validate_user_and_password - if @new_resource.user && use_password? - if @new_resource.password.nil? - Chef::Log.fatal "#{@new_resource.task_name}: Can't specify a non-system user without a password!" - end - end -end - -def validate_interactive_setting - if @new_resource.interactive_enabled && @new_resource.password.nil? - Chef::Log.fatal "#{new_resource} did not provide a password when attempting to set interactive/non-interactive." - end -end - -def validate_create_day - return unless @new_resource.day - unless [:weekly, :monthly].include?(@new_resource.frequency) - fail 'day attribute is only valid for tasks that run weekly or monthly' - end - if @new_resource.day.is_a? String - days = @new_resource.day.split(',') - days.each do |day| - unless ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun', '*'].include?(day.strip.downcase) - fail 'day attribute invalid. Only valid values are: MON, TUE, WED, THU, FRI, SAT, SUN and *. Multiple values must be separated by a comma.' - end - end - end -end - -def use_password? - @use_password ||= !SYSTEM_USERS.include?(@new_resource.user.upcase) -end diff --git a/cookbooks/windows/providers/zipfile.rb b/cookbooks/windows/providers/zipfile.rb deleted file mode 100644 index b050725..0000000 --- a/cookbooks/windows/providers/zipfile.rb +++ /dev/null @@ -1,90 +0,0 @@ -# -# Author:: Doug MacEachern () -# Author:: Seth Chisamore () -# Cookbook Name:: windows -# Provider:: zipfile -# -# Copyright:: 2010, VMware, Inc. -# Copyright:: 2011-2015, Chef Software, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -include Windows::Helper - -require 'find' - -action :unzip do - ensure_rubyzip_gem_installed - Chef::Log.debug("unzip #{@new_resource.source} => #{@new_resource.path} (overwrite=#{@new_resource.overwrite})") - - Zip::File.open(cached_file(@new_resource.source, @new_resource.checksum)) do |zip| - zip.each do |entry| - path = ::File.join(@new_resource.path, entry.name) - FileUtils.mkdir_p(::File.dirname(path)) - if @new_resource.overwrite && ::File.exist?(path) && !::File.directory?(path) - FileUtils.rm(path) - end - zip.extract(entry, path) - end - end - new_resource.updated_by_last_action(true) -end - -action :zip do - ensure_rubyzip_gem_installed - # sanitize paths for windows. - @new_resource.source.downcase.gsub!(::File::SEPARATOR, ::File::ALT_SEPARATOR) - @new_resource.path.downcase.gsub!(::File::SEPARATOR, ::File::ALT_SEPARATOR) - Chef::Log.debug("zip #{@new_resource.source} => #{@new_resource.path} (overwrite=#{@new_resource.overwrite})") - - if @new_resource.overwrite == false && ::File.exist?(@new_resource.path) - Chef::Log.info("file #{@new_resource.path} already exists and overwrite is set to false, exiting") - else - # delete the archive if it already exists, because we are recreating it. - ::File.unlink(@new_resource.path) if ::File.exist?(@new_resource.path) - # only supporting compression of a single directory (recursively). - if ::File.directory?(@new_resource.source) - z = Zip::File.new(@new_resource.path, true) - unless @new_resource.source =~ /::File::ALT_SEPARATOR$/ - @new_resource.source << ::File::ALT_SEPARATOR - end - Find.find(@new_resource.source) do |f| - f.downcase.gsub!(::File::SEPARATOR, ::File::ALT_SEPARATOR) - # don't add root directory to the zipfile. - next if f == @new_resource.source - # strip the root directory from the filename before adding it to the zipfile. - zip_fname = f.sub(@new_resource.source, '') - Chef::Log.debug("adding #{zip_fname} to archive, sourcefile is: #{f}") - z.add(zip_fname, f) - end - z.close - new_resource.updated_by_last_action(true) - else - Chef::Log.info("Single directory must be specified for compression, and #{@new_resource.source} does not meet that criteria.") - end - end -end - -private - -def ensure_rubyzip_gem_installed - require 'zip' -rescue LoadError - Chef::Log.info("Missing gem 'rubyzip'...installing now.") - chef_gem 'rubyzip' do - version node['windows']['rubyzipversion'] - action :install - end - require 'zip' -end diff --git a/cookbooks/windows/recipes/default.rb b/cookbooks/windows/recipes/default.rb index 4ca641e..c383261 100644 --- a/cookbooks/windows/recipes/default.rb +++ b/cookbooks/windows/recipes/default.rb @@ -1,34 +1,21 @@ -# -# Author:: Seth Chisamore () -# Cookbook Name:: windows -# Recipe:: default -# -# Copyright:: 2011-2015, Chef Software, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# gems with precompiled binaries -%w( win32-api win32-service ).each do |win_gem| - chef_gem win_gem do - options '--platform=mswin32' - action :install - end -end - -# the rest -%w( windows-api windows-pr win32-dir win32-event win32-mutex ).each do |win_gem| - chef_gem win_gem do - action :install - end -end +# +# Author:: Seth Chisamore () +# Cookbook:: windows +# Recipe:: default +# +# Copyright:: 2011-2017, Chef Software, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +Chef::Log.warn('The windows::default recipe has been deprecated. The gems previously installed in this recipe ship in the Chef MSI.') diff --git a/cookbooks/windows/recipes/reboot_handler.rb b/cookbooks/windows/recipes/reboot_handler.rb deleted file mode 100644 index 9f435b0..0000000 --- a/cookbooks/windows/recipes/reboot_handler.rb +++ /dev/null @@ -1,32 +0,0 @@ -# -# Author:: Seth Chisamore () -# Cookbook Name:: windows -# Recipe:: restart_handler -# -# Copyright:: 2011-2015, Chef Software, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -remote_directory node['chef_handler']['handler_path'] do - source 'handlers' - recursive true - action :create -end - -chef_handler 'WindowsRebootHandler' do - source "#{node['chef_handler']['handler_path']}/windows_reboot_handler.rb" - arguments node['windows']['allow_pending_reboots'] - supports report: true, exception: node['windows']['allow_reboot_on_failure'] - action :enable -end diff --git a/cookbooks/windows/resources/auto_run.rb b/cookbooks/windows/resources/auto_run.rb index ca9beaf..4330b99 100644 --- a/cookbooks/windows/resources/auto_run.rb +++ b/cookbooks/windows/resources/auto_run.rb @@ -1,30 +1,46 @@ -# -# Author:: Paul Morton () -# Cookbook Name:: windows -# Resource:: auto_run -# -# Copyright:: 2011, Business Intelligence Associates, Inc -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -def initialize(name, run_context = nil) - super - @action = :create -end - -actions :create, :remove - -attribute :program, kind_of: String -attribute :name, kind_of: String, name_attribute: true -attribute :args, kind_of: String, default: '' +# +# Author:: Paul Morton () +# Cookbook:: windows +# Resource:: auto_run +# +# Copyright:: 2011-2017, Business Intelligence Associates, Inc. +# Copyright:: 2017, Chef Software, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +property :program, String +property :name, String, name_property: true +property :args, String + +action :create do + registry_key 'HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run' do + values [{ + name: new_resource.name, + type: :string, + data: "\"#{new_resource.program}\" #{new_resource.args}", + }] + action :create + end +end + +action :remove do + registry_key 'HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run' do + values [{ + name: new_resource.name, + type: :string, + data: '', + }] + action :delete + end +end diff --git a/cookbooks/windows/resources/batch.rb b/cookbooks/windows/resources/batch.rb deleted file mode 100644 index 8fe73bd..0000000 --- a/cookbooks/windows/resources/batch.rb +++ /dev/null @@ -1,41 +0,0 @@ -# -# Author:: Seth Chisamore () -# Cookbook Name:: windows -# Resource:: batch -# -# Copyright:: 2011-2015, Chef Software, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -actions :run - -attribute :command, kind_of: String, name_attribute: true -attribute :cwd, kind_of: String, default: nil -attribute :code, kind_of: String, default: nil -attribute :user, kind_of: [String, Integer], default: nil -attribute :group, kind_of: [String, Integer], default: nil -attribute :creates, kind_of: [String], default: nil -attribute :flags, kind_of: [String], default: nil -attribute :returns, kind_of: [Integer, Array], default: 0 - -def initialize(name, run_context = nil) - super - @action = :run - @command = name - Chef::Log.warn <<-EOF -Please use the batch resource in Chef Client 11 and 12. -windows_batch will be removed in the next major version release -of the Windows cookbook. -EOF -end diff --git a/cookbooks/windows/resources/certificate.rb b/cookbooks/windows/resources/certificate.rb index 943ac1e..783093d 100644 --- a/cookbooks/windows/resources/certificate.rb +++ b/cookbooks/windows/resources/certificate.rb @@ -1,28 +1,166 @@ -# -# Author:: Richard Lavey (richard.lavey@calastone.com) -# Cookbook Name:: windows -# Resource:: certificate -# -# Copyright:: 2015, Calastone Ltd. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -actions :create, :delete, :acl_add -default_action :create - -attribute :source, kind_of: String, name_attribute: true, required: true -attribute :pfx_password, kind_of: String -attribute :private_key_acl, kind_of: Array -attribute :store_name, kind_of: String, default: 'MY', regex: /^(?:MY|CA|ROOT)$/ -attribute :user_store, kind_of: [TrueClass, FalseClass], default: false +# +# Author:: Richard Lavey (richard.lavey@calastone.com) +# Cookbook:: windows +# Resource:: certificate +# +# Copyright:: 2015-2017, Calastone Ltd. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +include Windows::Helper + +property :source, String, name_property: true, required: true +property :pfx_password, String +property :private_key_acl, Array +property :store_name, String, default: 'MY', regex: /^(?:MY|CA|ROOT|TrustedPublisher|TRUSTEDPEOPLE)$/ +property :user_store, [true, false], default: false + +action :create do + hash = '$cert.GetCertHashString()' + code_script = cert_script(true) << + within_store_script { |store| store + '.Add($cert)' } << + acl_script(hash) + + guard_script = cert_script(false) << + cert_exists_script(hash) + + converge_by("adding certificate #{new_resource.source} into #{new_resource.store_name} to #{cert_location}\\#{new_resource.store_name}") do + powershell_script new_resource.name do + guard_interpreter :powershell_script + convert_boolean_return true + code code_script + not_if guard_script + end + end +end + +# acl_add is a modify-if-exists operation : not idempotent +action :acl_add do + if ::File.exist?(new_resource.source) + hash = '$cert.GetCertHashString()' + code_script = cert_script(false) + guard_script = cert_script(false) + else + # make sure we have no spaces in the hash string + hash = "\"#{new_resource.source.gsub(/\s/, '')}\"" + code_script = '' + guard_script = '' + end + code_script << acl_script(hash) + guard_script << cert_exists_script(hash) + + converge_by("setting the acls on #{new_resource.source} in #{cert_location}\\#{new_resource.store_name}") do + powershell_script new_resource.name do + guard_interpreter :powershell_script + convert_boolean_return true + code code_script + only_if guard_script + end + end +end + +action :delete do + # do we have a hash or a subject? + # TODO: It's a bit annoying to know the thumbprint of a cert you want to remove when you already + # have the file. Support reading the hash directly from the file if provided. + search = if new_resource.source =~ /^[a-fA-F0-9]{40}$/ + "Thumbprint -eq '#{new_resource.source}'" + else + "Subject -like '*#{new_resource.source.sub(/\*/, '`*')}*'" # escape any * in the source + end + cert_command = "Get-ChildItem Cert:\\#{cert_location}\\#{new_resource.store_name} | where { $_.#{search} }" + + code_script = within_store_script do |store| + <<-EOH +foreach ($c in #{cert_command}) +{ + #{store}.Remove($c) +} +EOH + end + guard_script = "@(#{cert_command}).Count -gt 0\n" + converge_by("Removing certificate #{new_resource.source} from #{cert_location}\\#{new_resource.store_name}") do + powershell_script new_resource.name do + guard_interpreter :powershell_script + convert_boolean_return true + code code_script + only_if guard_script + end + end +end + +action_class do + def cert_location + @location ||= new_resource.user_store ? 'CurrentUser' : 'LocalMachine' + end + + def cert_script(persist) + cert_script = '$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2' + file = win_friendly_path(new_resource.source) + cert_script << " \"#{file}\"" + if ::File.extname(file.downcase) == '.pfx' + cert_script << ", \"#{new_resource.pfx_password}\"" + if persist && new_resource.user_store + cert_script << ', [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::PersistKeySet' + elsif persist + cert_script << ', ([System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::PersistKeySet -bor [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::MachineKeyset)' + end + end + cert_script << "\n" + end + + def cert_exists_script(hash) + <<-EOH + $hash = #{hash} + Test-Path "Cert:\\#{cert_location}\\#{new_resource.store_name}\\$hash" + EOH + end + + def within_store_script + inner_script = yield '$store' + <<-EOH + $store = New-Object System.Security.Cryptography.X509Certificates.X509Store "#{new_resource.store_name}", ([System.Security.Cryptography.X509Certificates.StoreLocation]::#{cert_location}) + $store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite) + #{inner_script} + $store.Close() + EOH + end + + def acl_script(hash) + return '' if new_resource.private_key_acl.nil? || new_resource.private_key_acl.empty? + # this PS came from http://blogs.technet.com/b/operationsguy/archive/2010/11/29/provide-access-to-private-keys-commandline-vs-powershell.aspx + # and from https://msdn.microsoft.com/en-us/library/windows/desktop/bb204778(v=vs.85).aspx + set_acl_script = <<-EOH + $hash = #{hash} + $storeCert = Get-ChildItem "cert:\\#{cert_location}\\#{new_resource.store_name}\\$hash" + if ($storeCert -eq $null) { throw 'no key exists.' } + $keyname = $storeCert.PrivateKey.CspKeyContainerInfo.UniqueKeyContainerName + if ($keyname -eq $null) { throw 'no private key exists.' } + if ($storeCert.PrivateKey.CspKeyContainerInfo.MachineKeyStore) + { + $fullpath = "$Env:ProgramData\\Microsoft\\Crypto\\RSA\\MachineKeys\\$keyname" + } + else + { + $currentUser = New-Object System.Security.Principal.NTAccount($Env:UserDomain, $Env:UserName) + $userSID = $currentUser.Translate([System.Security.Principal.SecurityIdentifier]).Value + $fullpath = "$Env:ProgramData\\Microsoft\\Crypto\\RSA\\$userSID\\$keyname" + } + EOH + new_resource.private_key_acl.each do |name| + set_acl_script << "$uname='#{name}'; icacls $fullpath /grant $uname`:RX\n" + end + set_acl_script + end +end diff --git a/cookbooks/windows/resources/certificate_binding.rb b/cookbooks/windows/resources/certificate_binding.rb index 63c97a1..507ab85 100644 --- a/cookbooks/windows/resources/certificate_binding.rb +++ b/cookbooks/windows/resources/certificate_binding.rb @@ -1,31 +1,128 @@ -# -# Author:: Richard Lavey (richard.lavey@calastone.com) -# Cookbook Name:: windows -# Resource:: certificate_binding -# -# Copyright:: 2015, Calastone Ltd. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -actions :create, :delete -default_action :create - -attribute :cert_name, kind_of: String, name_attribute: true, required: true -attribute :name_kind, kind_of: Symbol, equal_to: [:hash, :subject], default: :subject -attribute :address, kind_of: String, default: '0.0.0.0' -attribute :port, kind_of: Integer, default: 443 -attribute :app_id, kind_of: String, default: '{4dc3e181-e14b-4a21-b022-59fc669b0914}' -attribute :store_name, kind_of: String, default: 'MY', regex: /^(?:MY|CA|ROOT)$/ - -attr_accessor :exists +# +# Author:: Richard Lavey (richard.lavey@calastone.com) +# Cookbook:: windows +# Resource:: certificate_binding +# +# Copyright:: 2015-2017, Calastone Ltd. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +include Chef::Mixin::ShellOut +include Chef::Mixin::PowershellOut +include Windows::Helper + +property :cert_name, String, name_property: true, required: true +property :name_kind, Symbol, equal_to: [:hash, :subject], default: :subject +property :address, String, default: '0.0.0.0' +property :port, Integer, default: 443 +property :app_id, String, default: '{4dc3e181-e14b-4a21-b022-59fc669b0914}' +property :store_name, String, default: 'MY', regex: /^(?:MY|CA|ROOT)$/ +property :exists, [true, false], desired_state: true + +load_current_value do |desired| + cmd = shell_out("#{locate_sysnative_cmd('netsh.exe')} http show sslcert ipport=#{desired.address}:#{desired.port}") + Chef::Log.debug "netsh reports: #{cmd.stdout}" + + address desired.address + port desired.port + store_name desired.store_name + app_id desired.app_id + + if cmd.exitstatus == 0 + m = cmd.stdout.scan(/Certificate Hash\s+:\s?([A-Fa-f0-9]{40})/) + raise "Failed to extract hash from command output #{cmd.stdout}" if m.empty? + cert_name m[0][0] + name_kind :hash + exists true + else + exists false + end +end + +action :create do + hash = new_resource.name_kind == :subject ? hash_from_subject : new_resource.cert_name + + if current_resource.exists + needs_change = (hash.casecmp(current_resource.cert_name) != 0) + + if needs_change + converge_by("Changing #{current_resource.address}:#{current_resource.port}") do + delete_binding + add_binding hash + end + else + Chef::Log.debug("#{new_resource.address}:#{new_resource.port} already bound to #{hash} - nothing to do") + end + else + converge_by("Binding #{new_resource.address}:#{new_resource.port}") do + add_binding hash + end + end +end + +action :delete do + if current_resource.exists + converge_by("Deleting #{current_resource.address}:#{current_resource.port}") do + delete_binding + end + else + Chef::Log.debug("#{current_resource.address}:#{current_resource.port} not bound - nothing to do") + end +end + +action_class do + def netsh_command + locate_sysnative_cmd('netsh.exe') + end + + def add_binding(hash) + cmd = "#{netsh_command} http add sslcert" + cmd << " ipport=#{current_resource.address}:#{current_resource.port}" + cmd << " certhash=#{hash}" + cmd << " appid=#{current_resource.app_id}" + cmd << " certstorename=#{current_resource.store_name}" + check_hash hash + + shell_out!(cmd) + end + + def delete_binding + shell_out!("#{netsh_command} http delete sslcert ipport=#{current_resource.address}:#{current_resource.port}") + end + + def check_hash(hash) + p = powershell_out!("Test-Path \"cert:\\LocalMachine\\#{current_resource.store_name}\\#{hash}\"") + + unless p.stderr.empty? && p.stdout =~ /True/i + raise "A Cert with hash of #{hash} doesn't exist in keystore LocalMachine\\#{current_resource.store_name}" + end + nil + end + + def hash_from_subject + # escape wildcard subject name (*.acme.com) + subject = new_resource.cert_name.sub(/\*/, '`*') + ps_script = "& { gci cert:\\localmachine\\#{new_resource.store_name} | where { $_.subject -like '*#{subject}*' } | select -first 1 -expandproperty Thumbprint }" + + Chef::Log.debug "Running PS script #{ps_script}" + p = powershell_out!(ps_script) + + raise "#{ps_script} failed with #{p.stderr}" if !p.stderr.nil? && !p.stderr.empty? + raise "Couldn't find thumbprint for subject #{new_resource.cert_name}" if p.stdout.nil? || p.stdout.empty? + + # seem to get a UTF-8 string with BOM returned sometimes! Strip any such BOM + hash = p.stdout.strip + hash[0].ord == 239 ? hash.force_encoding('UTF-8').delete!("\xEF\xBB\xBF".force_encoding('UTF-8')) : hash + end +end diff --git a/cookbooks/windows/resources/feature.rb b/cookbooks/windows/resources/feature.rb index 47f7340..e55ff5a 100644 --- a/cookbooks/windows/resources/feature.rb +++ b/cookbooks/windows/resources/feature.rb @@ -1,47 +1,82 @@ -# -# Author:: Seth Chisamore () -# Cookbook Name:: windows -# Resource:: feature -# -# Copyright:: 2011-2015, Chef Software, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -include Windows::Helper - -actions :install, :remove, :delete - -attribute :feature_name, kind_of: String, name_attribute: true -attribute :source, kind_of: String -attribute :all, kind_of: [TrueClass, FalseClass], default: false - -def initialize(name, run_context = nil) - super - @action = :install - @provider = lookup_provider_constant(locate_default_provider) -end - -private - -def locate_default_provider - if node['windows'].attribute?(:feature_provider) - "windows_feature_#{node['windows']['feature_provider']}" - elsif ::File.exist?(locate_sysnative_cmd('dism.exe')) - :windows_feature_dism - elsif ::File.exist?(locate_sysnative_cmd('servermanagercmd.exe')) - :windows_feature_servermanagercmd - else - :windows_feature_powershell - end -end +# +# Author:: Seth Chisamore () +# Cookbook:: windows +# Resource:: feature +# +# Copyright:: 2011-2017, Chef Software, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +property :feature_name, [Array, String], name_property: true +property :source, String +property :all, [true, false], default: false +property :install_method, Symbol, equal_to: [:windows_feature_dism, :windows_feature_powershell, :windows_feature_servermanagercmd] + +include Windows::Helper + +def whyrun_supported? + true +end + +action :install do + run_default_provider :install +end + +action :remove do + run_default_provider :remove +end + +action :delete do + run_default_provider :delete +end + +action_class do + def locate_default_provider + if new_resource.install_method + new_resource.install_method + elsif ::File.exist?(locate_sysnative_cmd('dism.exe')) + :windows_feature_dism + elsif ::File.exist?(locate_sysnative_cmd('servermanagercmd.exe')) + :windows_feature_servermanagercmd + else + :windows_feature_powershell + end + end + + def run_default_provider(desired_action) + case locate_default_provider + when :windows_feature_dism + windows_feature_dism new_resource.name do + action desired_action + feature_name new_resource.feature_name + source new_resource.source if new_resource.source + all new_resource.all + end + when :windows_feature_servermanagercmd + windows_feature_servermanagercmd new_resource.name do + action desired_action + feature_name new_resource.feature_name + source new_resource.source if new_resource.source + all new_resource.all + end + when :windows_feature_powershell + windows_feature_powershell new_resource.name do + action desired_action + feature_name new_resource.feature_name + source new_resource.source if new_resource.source + all new_resource.all + end + end + end +end diff --git a/cookbooks/windows/resources/feature_dism.rb b/cookbooks/windows/resources/feature_dism.rb new file mode 100644 index 0000000..9a9da56 --- /dev/null +++ b/cookbooks/windows/resources/feature_dism.rb @@ -0,0 +1,108 @@ +# +# Author:: Seth Chisamore () +# Cookbook:: windows +# Provider:: feature_dism +# +# Copyright:: 2011-2017, Chef Software, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +property :feature_name, [Array, String], name_property: true +property :source, String +property :all, [true, false], default: false + +include Chef::Mixin::ShellOut +include Windows::Helper + +action :install do + Chef::Log.warn("Requested feature #{new_resource.feature_name} is not available on this system.") unless available? + unless !available? || installed? + converge_by("install Windows feature #{new_resource.feature_name}") do + addsource = new_resource.source ? "/LimitAccess /Source:\"#{new_resource.source}\"" : '' + addall = new_resource.all ? '/All' : '' + shell_out!("#{dism} /online /enable-feature #{to_array(new_resource.feature_name).map { |feature| "/featurename:#{feature}" }.join(' ')} /norestart #{addsource} #{addall}", returns: [0, 42, 127, 3010]) + # Reload ohai data + reload_ohai_features_plugin(new_resource.action, new_resource.feature_name) + end + end +end + +action :remove do + if installed? + converge_by("removing Windows feature #{new_resource.feature_name}") do + shell_out!("#{dism} /online /disable-feature #{to_array(new_resource.feature_name).map { |feature| "/featurename:#{feature}" }.join(' ')} /norestart", returns: [0, 42, 127, 3010]) + # Reload ohai data + reload_ohai_features_plugin(new_resource.action, new_resource.feature_name) + end + end +end + +action :delete do + raise Chef::Exceptions::UnsupportedAction, "#{self} :delete action not support on #{win_version.sku}" unless supports_feature_delete? + if available? + converge_by("deleting Windows feature #{new_resource.feature_name} from the image") do + shell_out!("#{dism} /online /disable-feature #{to_array(new_resource.feature_name).map { |feature| "/featurename:#{feature}" }.join(' ')} /Remove /norestart", returns: [0, 42, 127, 3010]) + # Reload ohai data + reload_ohai_features_plugin(new_resource.action, new_resource.feature_name) + end + end +end + +action_class do + def installed? + @installed ||= begin + install_ohai_plugin unless node['dism_features'] + + # Compare against ohai plugin instead of costly dism run + node['dism_features'].key?(new_resource.feature_name) && node['dism_features'][new_resource.feature_name] =~ /Enable/ + end + end + + def available? + @available ||= begin + install_ohai_plugin unless node['dism_features'] + + # Compare against ohai plugin instead of costly dism run + node['dism_features'].key?(new_resource.feature_name) && node['dism_features'][new_resource.feature_name] !~ /with payload removed/ + end + end + + def reload_ohai_features_plugin(take_action, feature_name) + ohai "Reloading Dism_Features Plugin - Action #{take_action} of feature #{feature_name}" do + action :reload + plugin 'dism_features' + end + end + + def install_ohai_plugin + Chef::Log.info("node['dism_features'] data missing. Installing the dism_features Ohai plugin") + + ohai_plugin 'dism_features' do + compile_time true + cookbook 'windows' + end + end + + def supports_feature_delete? + win_version.major_version >= 6 && win_version.minor_version >= 2 + end + + # account for File System Redirector + # http://msdn.microsoft.com/en-us/library/aa384187(v=vs.85).aspx + def dism + @dism ||= begin + locate_sysnative_cmd('dism.exe') + end + end +end diff --git a/cookbooks/windows/resources/feature_powershell.rb b/cookbooks/windows/resources/feature_powershell.rb new file mode 100644 index 0000000..04d6687 --- /dev/null +++ b/cookbooks/windows/resources/feature_powershell.rb @@ -0,0 +1,70 @@ +# +# Author:: Greg Zapp () +# Cookbook:: windows +# Provider:: feature_powershell +# + +property :feature_name, [Array, String], name_attribute: true +property :source, String +property :all, [true, false], default: false + +include Chef::Mixin::PowershellOut +include Windows::Helper + +action :remove do + if installed? + converge_by("remove Windows feature #{new_resource.feature_name}") do + cmd = powershell_out!("#{remove_feature_cmdlet} #{to_array(new_resource.feature_name).join(',')}") + Chef::Log.info(cmd.stdout) + end + end +end + +action :delete do + if available? + converge_by("delete Windows feature #{new_resource.feature_name} from the image") do + cmd = powershell_out!("Uninstall-WindowsFeature #{to_array(new_resource.feature_name).join(',')} -Remove") + Chef::Log.info(cmd.stdout) + end + end +end + +action_class do + def install_feature_cmdlet + node['os_version'].to_f < 6.2 ? 'Import-Module ServerManager; Add-WindowsFeature' : 'Install-WindowsFeature' + end + + def remove_feature_cmdlet + node['os_version'].to_f < 6.2 ? 'Import-Module ServerManager; Remove-WindowsFeature' : 'Uninstall-WindowsFeature' + end + + def installed? + @installed ||= begin + cmd = powershell_out("(Get-WindowsFeature #{to_array(new_resource.feature_name).join(',')} | ?{$_.InstallState -ne \'Installed\'}).count") + cmd.stderr.empty? && cmd.stdout.chomp.to_i == 0 + end + end + + def available? + @available ||= begin + cmd = powershell_out("(Get-WindowsFeature #{to_array(new_resource.feature_name).join(',')} | ?{$_.InstallState -ne \'Removed\'}).count") + cmd.stderr.empty? && cmd.stdout.chomp.to_i > 0 + end + end +end + +action :install do + Chef::Log.warn("Requested feature #{new_resource.feature_name} is not available on this system.") unless available? + unless !available? || installed? + converge_by("install Windows feature #{new_resource.feature_name}") do + addsource = new_resource.source ? "-Source \"#{new_resource.source}\"" : '' + addall = new_resource.all ? '-IncludeAllSubFeature' : '' + cmd = if node['os_version'].to_f < 6.2 + powershell_out!("#{install_feature_cmdlet} #{to_array(new_resource.feature_name).join(',')} #{addall}") + else + powershell_out!("#{install_feature_cmdlet} #{to_array(new_resource.feature_name).join(',')} #{addsource} #{addall}") + end + Chef::Log.info(cmd.stdout) + end + end +end diff --git a/cookbooks/windows/resources/feature_servermanagercmd.rb b/cookbooks/windows/resources/feature_servermanagercmd.rb new file mode 100644 index 0000000..3b68ea4 --- /dev/null +++ b/cookbooks/windows/resources/feature_servermanagercmd.rb @@ -0,0 +1,76 @@ +# +# Author:: Seth Chisamore () +# Cookbook:: windows +# Provider:: feature_servermanagercmd +# +# Copyright:: 2011-2017, Chef Software, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +property :feature_name, [Array, String], name_attribute: true +property :source, String +property :all, [true, false], default: false + +include Chef::Mixin::ShellOut +include Windows::Helper + +action :install do + unless installed? + converge_by("install Windows feature #{new_resource.feature_name}") do + check_reboot(shell_out("#{servermanagercmd} -install #{to_array(new_resource.feature_name).join(' ')}", returns: [0, 42, 127, 1003, 3010]), new_resource.feature_name) + end + end +end + +action :remove do + if installed? + converge_by("removing Windows feature #{new_resource.feature_name}") do + check_reboot(shell_out("#{servermanagercmd} -remove #{to_array(new_resource.feature_name).join(' ')}", returns: [0, 42, 127, 1003, 3010]), new_resource.feature_name) + end + end +end + +action :delete do + Chef::Log.warn('servermanagercmd does not support removing a feature from the image.') +end + +# Exit codes are listed at http://technet.microsoft.com/en-us/library/cc749128(v=ws.10).aspx + +action_class do + def check_reboot(result, feature) + if result.exitstatus == 3010 # successful, but needs reboot + node.run_state['reboot_requested'] = true + Chef::Log.warn("Require reboot to install #{feature}") + elsif result.exitstatus == 1001 # failure, but needs reboot before we can do anything else + node.run_state['reboot_requested'] = true + Chef::Log.warn("Failed installing #{feature} and need to reboot") + end + result.error! # throw for any other bad results. The above results will also get raised, and should cause a reboot via the handler. + end + + def installed? + @installed ||= begin + cmd = shell_out("#{servermanagercmd} -query", returns: [0, 42, 127, 1003]) + cmd.stderr.empty? && (cmd.stdout =~ /^\s*?\[X\]\s.+?\s\[#{new_resource.feature_name}\]\s*$/i) + end + end + + # account for File System Redirector + # http://msdn.microsoft.com/en-us/library/aa384187(v=vs.85).aspx + def servermanagercmd + @servermanagercmd ||= begin + locate_sysnative_cmd('servermanagercmd.exe') + end + end +end diff --git a/cookbooks/windows/resources/font.rb b/cookbooks/windows/resources/font.rb index f930db4..997333e 100644 --- a/cookbooks/windows/resources/font.rb +++ b/cookbooks/windows/resources/font.rb @@ -1,25 +1,80 @@ -# -# Author:: Sander Botman -# Cookbook Name:: windows -# Resource:: font -# -# Copyright:: 2014, Schuberg Philis BV. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -actions :install - -default_action :install - -attribute :file, kind_of: String, name_attribute: true +# +# Author:: Sander Botman +# Cookbook:: windows +# Resource:: font +# +# Copyright:: 2014-2017, Schuberg Philis BV. +# Copyright:: 2017, Chef Software, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +property :name, String, name_property: true +property :source, String, required: false + +include Windows::Helper + +action :install do + if font_exists? + Chef::Log.debug("Not installing font: #{new_resource.name}, font already installed.") + else + retrieve_cookbook_font + install_font + del_cookbook_font + end +end + +action_class do + def retrieve_cookbook_font + font_file = new_resource.name + if new_resource.source + remote_file font_file do + action :nothing + source "file://#{new_resource.source}" + path win_friendly_path(::File.join(ENV['TEMP'], font_file)) + end.run_action(:create) + else + cookbook_file font_file do + action :nothing + cookbook cookbook_name.to_s unless cookbook_name.nil? + path win_friendly_path(::File.join(ENV['TEMP'], font_file)) + end.run_action(:create) + end + end + + def del_cookbook_font + file ::File.join(ENV['TEMP'], new_resource.name) do + action :delete + end + end + + def install_font + require 'win32ole' if RUBY_PLATFORM =~ /mswin|mingw32|windows/ + fonts_dir = WIN32OLE.new('WScript.Shell').SpecialFolders('Fonts') + folder = WIN32OLE.new('Shell.Application').Namespace(fonts_dir) + converge_by("install font #{new_resource.name}") do + folder.CopyHere(win_friendly_path(::File.join(ENV['TEMP'], new_resource.name))) + end + end + + # Check to see if the font is installed + # + # === Returns + # :: If the font is installed + # :: If the font is not instaled + def font_exists? + require 'win32ole' if RUBY_PLATFORM =~ /mswin|mingw32|windows/ + fonts_dir = WIN32OLE.new('WScript.Shell').SpecialFolders('Fonts') + ::File.exist?(win_friendly_path(::File.join(fonts_dir, new_resource.name))) + end +end diff --git a/cookbooks/windows/resources/http_acl.rb b/cookbooks/windows/resources/http_acl.rb index 2a20126..0dacb50 100644 --- a/cookbooks/windows/resources/http_acl.rb +++ b/cookbooks/windows/resources/http_acl.rb @@ -1,27 +1,110 @@ -# -# Author:: Richard Lavey (richard.lavey@calastone.com) -# Cookbook Name:: windows -# Resource:: http_acl -# -# Copyright:: 2015, Calastone Ltd. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -actions :create, :delete -default_action :create - -attribute :url, kind_of: String, name_attribute: true, required: true -attribute :user, kind_of: String - -attr_accessor :exists +# +# Author:: Richard Lavey (richard.lavey@calastone.com) +# Cookbook:: windows +# Resource:: http_acl +# +# Copyright:: 2015-2017, Calastone Ltd. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +include Chef::Mixin::ShellOut +include Windows::Helper + +property :url, String, name_property: true, required: true +property :user, String +property :sddl, String +property :exists, [true, false], desired_state: true + +# See https://msdn.microsoft.com/en-us/library/windows/desktop/cc307236%28v=vs.85%29.aspx for netsh info + +load_current_value do |desired| + cmd_out = shell_out!("#{locate_sysnative_cmd('netsh.exe')} http show urlacl url=#{desired.url}").stdout + Chef::Log.debug "netsh reports: #{cmd_out}" + + if cmd_out.include? desired.url + exists true + url desired.url + # Checks first for sddl, because it generates user(s) + sddl_match = cmd_out.match(/SDDL:\s*(?.+)/) + if sddl_match + sddl sddl_match['sddl'] + else + # if no sddl, tries to find a single user + user_match = cmd_out.match(/User:\s*(?.+)/) + user user_match['user'] + end + else + exists false + end +end + +action :create do + raise '`user` xor `sddl` can\'t be used together' if new_resource.user && new_resource.sddl + raise 'When provided user property can\'t be empty' if new_resource.user && new_resource.user.empty? + raise 'When provided sddl property can\'t be empty' if new_resource.sddl && new_resource.sddl.empty? + + if current_resource.exists + sddl_changed = ( + new_resource.sddl && + current_resource.sddl && + current_resource.sddl.casecmp(new_resource.sddl) != 0 + ) + user_changed = ( + new_resource.user && + current_resource.user && + current_resource.user.casecmp(new_resource.user) != 0 + ) + + if sddl_changed || user_changed + converge_by("Changing #{new_resource.url}") do + delete_acl + apply_acl + end + else + Chef::Log.debug("#{new_resource.url} already set - nothing to do") + end + else + converge_by("Setting #{new_resource.url}") do + apply_acl + end + end +end + +action :delete do + if current_resource.exists + converge_by("Deleting #{new_resource.url}") do + delete_acl + end + else + Chef::Log.debug("#{new_resource.url} does not exist - nothing to do") + end +end + +action_class do + def netsh_command + locate_sysnative_cmd('netsh.exe') + end + + def apply_acl + if current_resource.sddl + shell_out!("#{netsh_command} http add urlacl url=#{new_resource.url} sddl=\"#{new_resource.sddl}\"") + else + shell_out!("#{netsh_command} http add urlacl url=#{new_resource.url} user=\"#{new_resource.user}\"") + end + end + + def delete_acl + shell_out!("#{netsh_command} http delete urlacl url=#{new_resource.url}") + end +end diff --git a/cookbooks/windows/resources/pagefile.rb b/cookbooks/windows/resources/pagefile.rb index d0ca6e3..60977c2 100644 --- a/cookbooks/windows/resources/pagefile.rb +++ b/cookbooks/windows/resources/pagefile.rb @@ -1,29 +1,156 @@ -# -# Author:: Kevin Moser () -# Cookbook Name:: windows -# Resource:: pagefile -# -# Copyright:: 2012, Nordstrom, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -actions :set, :delete - -attribute :name, kind_of: String, name_attribute: true -attribute :system_managed, kind_of: [TrueClass, FalseClass] -attribute :automatic_managed, kind_of: [TrueClass, FalseClass], default: false -attribute :initial_size, kind_of: Integer -attribute :maximum_size, kind_of: Integer - -default_action :set +# +# Author:: Kevin Moser () +# Cookbook:: windows +# Resource:: pagefile +# +# Copyright:: 2012-2017, Nordstrom, Inc. +# Copyright:: 2017, Chef Software, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +property :name, String, name_property: true +property :system_managed, [true, false] +property :automatic_managed, [true, false], default: false +property :initial_size, Integer +property :maximum_size, Integer + +include Chef::Mixin::ShellOut +include Windows::Helper + +action :set do + pagefile = new_resource.name + initial_size = new_resource.initial_size + maximum_size = new_resource.maximum_size + system_managed = new_resource.system_managed + automatic_managed = new_resource.automatic_managed + + if automatic_managed + set_automatic_managed unless automatic_managed? + else + unset_automatic_managed if automatic_managed? + + # Check that the resource is not just trying to unset automatic managed, if it is do nothing more + if (initial_size && maximum_size) || system_managed + validate_name + create(pagefile) unless exists?(pagefile) + + if system_managed + set_system_managed(pagefile) unless max_and_min_set?(pagefile, 0, 0) + else + unless max_and_min_set?(pagefile, initial_size, maximum_size) + set_custom_size(pagefile, initial_size, maximum_size) + end + end + end + end +end + +action :delete do + validate_name + pagefile = new_resource.name + delete(pagefile) if exists?(pagefile) +end + +action_class do + def validate_name + return if /^.:.*.sys/ =~ new_resource.name + raise "#{new_resource.name} does not match the format DRIVE:\\path\\file.sys for pagefiles. Example: C:\\pagefile.sys" + end + + def exists?(pagefile) + @exists ||= begin + Chef::Log.debug("Checking if #{pagefile} exists by runing: #{wmic} pagefileset where SettingID=\"#{get_setting_id(pagefile)}\" list /format:list") + cmd = shell_out("#{wmic} pagefileset where SettingID=\"#{get_setting_id(pagefile)}\" list /format:list", returns: [0]) + cmd.stderr.empty? && (cmd.stdout =~ /SettingID=#{get_setting_id(pagefile)}/i) + end + end + + def max_and_min_set?(pagefile, min, max) + @max_and_min_set ||= begin + Chef::Log.debug("Checking if #{pagefile} min: #{min} and max #{max} are set") + cmd = shell_out("#{wmic} pagefileset where SettingID=\"#{get_setting_id(pagefile)}\" list /format:list", returns: [0]) + cmd.stderr.empty? && (cmd.stdout =~ /InitialSize=#{min}/i) && (cmd.stdout =~ /MaximumSize=#{max}/i) + end + end + + def create(pagefile) + converge_by("create pagefile #{pagefile}") do + Chef::Log.debug("Running #{wmic} pagefileset create name=\"#{win_friendly_path(pagefile)}\"") + cmd = shell_out("#{wmic} pagefileset create name=\"#{win_friendly_path(pagefile)}\"") + check_for_errors(cmd.stderr) + end + end + + def delete(pagefile) + converge_by("remove pagefile #{pagefile}") do + Chef::Log.debug("Running #{wmic} pagefileset where SettingID=\"#{get_setting_id(pagefile)}\" delete") + cmd = shell_out("#{wmic} pagefileset where SettingID=\"#{get_setting_id(pagefile)}\" delete") + check_for_errors(cmd.stderr) + end + end + + def automatic_managed? + @automatic_managed ||= begin + Chef::Log.debug('Checking if pagefiles are automatically managed') + cmd = shell_out("#{wmic} computersystem where name=\"%computername%\" get AutomaticManagedPagefile /format:list") + cmd.stderr.empty? && (cmd.stdout =~ /AutomaticManagedPagefile=TRUE/i) + end + end + + def set_automatic_managed + converge_by('set pagefile to Automatic Managed') do + Chef::Log.debug("Running #{wmic} computersystem where name=\"%computername%\" set AutomaticManagedPagefile=True") + cmd = shell_out("#{wmic} computersystem where name=\"%computername%\" set AutomaticManagedPagefile=True") + check_for_errors(cmd.stderr) + end + end + + def unset_automatic_managed + converge_by('set pagefile to User Managed') do + Chef::Log.debug("Running #{wmic} computersystem where name=\"%computername%\" set AutomaticManagedPagefile=False") + cmd = shell_out("#{wmic} computersystem where name=\"%computername%\" set AutomaticManagedPagefile=False") + check_for_errors(cmd.stderr) + end + end + + def set_custom_size(pagefile, min, max) + converge_by("set #{pagefile} to InitialSize=#{min} & MaximumSize=#{max}") do + Chef::Log.debug("Running #{wmic} pagefileset where SettingID=\"#{get_setting_id(pagefile)}\" set InitialSize=#{min},MaximumSize=#{max}") + cmd = shell_out("#{wmic} pagefileset where SettingID=\"#{get_setting_id(pagefile)}\" set InitialSize=#{min},MaximumSize=#{max}", returns: [0]) + check_for_errors(cmd.stderr) + end + end + + def set_system_managed(pagefile) # rubocop: disable Style/AccessorMethodName + converge_by("set #{pagefile} to System Managed") do + Chef::Log.debug("Running #{wmic} pagefileset where SettingID=\"#{get_setting_id(pagefile)}\" set InitialSize=0,MaximumSize=0") + cmd = shell_out("#{wmic} pagefileset where SettingID=\"#{get_setting_id(pagefile)}\" set InitialSize=0,MaximumSize=0", returns: [0]) + check_for_errors(cmd.stderr) + end + end + + def get_setting_id(pagefile) + pagefile = win_friendly_path(pagefile) + pagefile = pagefile.split('\\') + "#{pagefile[1]} @ #{pagefile[0]}" + end + + def check_for_errors(stderr) + raise stderr.chomp unless stderr.empty? + end + + def wmic + @wmic ||= locate_sysnative_cmd('wmic.exe') + end +end diff --git a/cookbooks/windows/resources/path.rb b/cookbooks/windows/resources/path.rb index a496c03..21a22a8 100644 --- a/cookbooks/windows/resources/path.rb +++ b/cookbooks/windows/resources/path.rb @@ -1,28 +1,54 @@ -# -# Author:: Paul Morton () -# Cookbook Name:: windows -# Resource:: path -# -# Copyright:: 2011, Business Intelligence Associates, Inc -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -def initialize(name, run_context = nil) - super - @action = :add -end - -actions :add, :remove - -attribute :path, kind_of: String, name_attribute: true +# +# Author:: Paul Morton () +# Cookbook:: windows +# Resource:: path +# +# Copyright:: 2011-2017, Business Intelligence Associates, Inc +# Copyright:: 2017, Chef Software, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +property :path, String, name_property: true + +include Windows::Helper + +action :add do + env 'path' do + action :modify + delim ::File::PATH_SEPARATOR + value new_resource.path.tr('/', '\\') + notifies :run, "ruby_block[fix ruby ENV['PATH']]", :immediately + end + + # The windows Env provider does not correctly expand variables in + # the PATH environment variable. Ruby expects these to be expanded. + # This is a temporary fix for that. + # + # Follow at https://github.com/chef/chef/pull/1876 + # + ruby_block "fix ruby ENV['PATH']" do + block do + ENV['PATH'] = expand_env_vars(ENV['PATH']) + end + action :nothing + end +end + +action :remove do + env 'path' do + action :delete + delim ::File::PATH_SEPARATOR + value new_resource.path.tr('/', '\\') + end +end diff --git a/cookbooks/windows/resources/printer.rb b/cookbooks/windows/resources/printer.rb index 2555660..2997fa8 100644 --- a/cookbooks/windows/resources/printer.rb +++ b/cookbooks/windows/resources/printer.rb @@ -1,41 +1,103 @@ -# -# Author:: Doug Ireton () -# Cookbook Name:: windows -# Resource:: printer -# -# Copyright:: 2012, Nordstrom, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# See here for more info: -# http://msdn.microsoft.com/en-us/library/windows/desktop/aa394492(v=vs.85).aspx - -require 'resolv' - -actions :create, :delete - -default_action :create - -attribute :device_id, kind_of: String, name_attribute: true, - required: true -attribute :comment, kind_of: String - -attribute :default, kind_of: [TrueClass, FalseClass], default: false -attribute :driver_name, kind_of: String, required: true -attribute :location, kind_of: String -attribute :shared, kind_of: [TrueClass, FalseClass], default: false -attribute :share_name, kind_of: String - -attribute :ipv4_address, kind_of: String, regex: Resolv::IPv4::Regex - -attr_accessor :exists +# +# Author:: Doug Ireton () +# Cookbook:: windows +# Resource:: printer +# +# Copyright:: 2012-2017, Nordstrom, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# See here for more info: +# http://msdn.microsoft.com/en-us/library/windows/desktop/aa394492(v=vs.85).aspx + +require 'resolv' + +property :device_id, String, name_property: true, required: true +property :comment, String +property :default, [true, false], default: false +property :driver_name, String, required: true +property :location, String +property :shared, [true, false], default: false +property :share_name, String +property :ipv4_address, String, regex: Resolv::IPv4::Regex +property :exists, [true, false], desired_state: true + +PRINTERS_REG_KEY = 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Printers\\'.freeze unless defined?(PRINTERS_REG_KEY) + +def printer_exists?(name) + printer_reg_key = PRINTERS_REG_KEY + name + Chef::Log.debug "Checking to see if this reg key exists: '#{printer_reg_key}'" + Registry.key_exists?(printer_reg_key) +end + +load_current_value do |desired| + name desired.name + exists printer_exists?(desired.name) + # TODO: Set @current_resource printer properties from registry +end + +action :create do + if @current_resource.exists + Chef::Log.info "#{@new_resource} already exists - nothing to do." + else + converge_by("Create #{@new_resource}") do + create_printer + end + end +end + +action :delete do + if @current_resource.exists + converge_by("Delete #{@new_resource}") do + delete_printer + end + else + Chef::Log.info "#{@current_resource} doesn't exist - can't delete." + end +end + +action_class do + def create_printer + # Create the printer port first + windows_printer_port new_resource.ipv4_address do + end + + port_name = "IP_#{new_resource.ipv4_address}" + + powershell_script "Creating printer: #{new_resource.name}" do + code <<-EOH + + Set-WmiInstance -class Win32_Printer ` + -EnableAllPrivileges ` + -Argument @{ DeviceID = "#{new_resource.device_id}"; + Comment = "#{new_resource.comment}"; + Default = "$#{new_resource.default}"; + DriverName = "#{new_resource.driver_name}"; + Location = "#{new_resource.location}"; + PortName = "#{port_name}"; + Shared = "$#{new_resource.shared}"; + ShareName = "#{new_resource.share_name}"; + } + EOH + end + end + + def delete_printer + powershell_script "Deleting printer: #{new_resource.name}" do + code <<-EOH + $printer = Get-WMIObject -class Win32_Printer -EnableAllPrivileges -Filter "name = '#{new_resource.name}'" + $printer.Delete() + EOH + end + end +end diff --git a/cookbooks/windows/resources/printer_port.rb b/cookbooks/windows/resources/printer_port.rb index 70eff93..1629db3 100644 --- a/cookbooks/windows/resources/printer_port.rb +++ b/cookbooks/windows/resources/printer_port.rb @@ -1,40 +1,101 @@ -# -# Author:: Doug Ireton () -# Cookbook Name:: windows -# Resource:: printer_port -# -# Copyright:: 2012, Nordstrom, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# See here for more info: -# http://msdn.microsoft.com/en-us/library/windows/desktop/aa394492(v=vs.85).aspx - -require 'resolv' - -actions :create, :delete - -default_action :create - -attribute :ipv4_address, name_attribute: true, kind_of: String, - required: true, regex: Resolv::IPv4::Regex - -attribute :port_name, kind_of: String -attribute :port_number, kind_of: Fixnum, default: 9100 -attribute :port_description, kind_of: String -attribute :snmp_enabled, kind_of: [TrueClass, FalseClass], - default: false - -attribute :port_protocol, kind_of: Fixnum, default: 1, equal_to: [1, 2] - -attr_accessor :exists +# +# Author:: Doug Ireton () +# Cookbook:: windows +# Resource:: printer_port +# +# Copyright:: 2012-2017, Nordstrom, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# See here for more info: +# http://msdn.microsoft.com/en-us/library/windows/desktop/aa394492(v=vs.85).aspx + +require 'resolv' + +property :ipv4_address, String, name_attribute: true, required: true, regex: Resolv::IPv4::Regex +property :port_name, String +property :port_number, Integer, default: 9100 +property :port_description, String +property :snmp_enabled, [true, false], default: false +property :port_protocol, Integer, default: 1, equal_to: [1, 2] +property :exists, [true, false], desired_state: true + +PORTS_REG_KEY = 'HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Print\Monitors\Standard TCP/IP Port\Ports\\'.freeze unless defined?(PORTS_REG_KEY) + +def port_exists?(name) + port_reg_key = PORTS_REG_KEY + name + + Chef::Log.debug "Checking to see if this reg key exists: '#{port_reg_key}'" + Registry.key_exists?(port_reg_key) +end + +load_current_value do |desired| + name desired.name + ipv4_address desired.ipv4_address + port_name desired.port_name || "IP_#{@new_resource.ipv4_address}" + exists port_exists?(desired.port_name) + # TODO: Set @current_resource port properties from registry +end + +action :create do + if current_resource.exists + Chef::Log.info "#{@new_resource} already exists - nothing to do." + else + converge_by("Create #{@new_resource}") do + create_printer_port + end + end +end + +action :delete do + if current_resource.exists + converge_by("Delete #{@new_resource}") do + delete_printer_port + end + else + Chef::Log.info "#{@current_resource} doesn't exist - can't delete." + end +end + +action_class do + def create_printer_port + port_name = new_resource.port_name || "IP_#{new_resource.ipv4_address}" + + # create the printer port using PowerShell + powershell_script "Creating printer port #{new_resource.port_name}" do + code <<-EOH + + Set-WmiInstance -class Win32_TCPIPPrinterPort ` + -EnableAllPrivileges ` + -Argument @{ HostAddress = "#{new_resource.ipv4_address}"; + Name = "#{port_name}"; + Description = "#{new_resource.port_description}"; + PortNumber = "#{new_resource.port_number}"; + Protocol = "#{new_resource.port_protocol}"; + SNMPEnabled = "$#{new_resource.snmp_enabled}"; + } + EOH + end + end + + def delete_printer_port + port_name = new_resource.port_name || "IP_#{new_resource.ipv4_address}" + + powershell_script "Deleting printer port: #{new_resource.port_name}" do + code <<-EOH + $port = Get-WMIObject -class Win32_TCPIPPrinterPort -EnableAllPrivileges -Filter "name = '#{port_name}'" + $port.Delete() + EOH + end + end +end diff --git a/cookbooks/windows/resources/reboot.rb b/cookbooks/windows/resources/reboot.rb deleted file mode 100644 index af1eeb1..0000000 --- a/cookbooks/windows/resources/reboot.rb +++ /dev/null @@ -1,34 +0,0 @@ -# -# Author:: Seth Chisamore () -# Cookbook Name:: windows -# Resource:: reboot -# -# Copyright:: 2011-2015, Chef Software, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -actions :request, :cancel - -attribute :timeout, kind_of: Integer, name_attribute: true -attribute :reason, kind_of: String, default: 'Chef client run' - -def initialize(name, run_context = nil) - super - @action = :request - Chef::Log.warn <<-EOF -The windows_reboot resource is deprecated. Please use the reboot resource in -Chef Client 12. windows_reboot will be removed in the next major version -release of the Windows cookbook. -EOF -end diff --git a/cookbooks/windows/resources/registry.rb b/cookbooks/windows/resources/registry.rb deleted file mode 100644 index 1d1b3f3..0000000 --- a/cookbooks/windows/resources/registry.rb +++ /dev/null @@ -1,38 +0,0 @@ -# -# Author:: Doug MacEachern () -# Author:: Seth Chisamore () -# Cookbook Name:: windows -# Resource:: registry -# -# Copyright:: 2010, VMware, Inc. -# Copyright:: 2011-2015, Chef Software, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -actions :create, :modify, :force_modify, :remove - -attribute :key_name, kind_of: String, name_attribute: true -attribute :values, kind_of: Hash -attribute :type, kind_of: Symbol, default: nil, equal_to: [:binary, :string, :multi_string, :expand_string, :dword, :dword_big_endian, :qword] - -def initialize(name, run_context = nil) - super - @action = :modify - @key_name = name - Chef::Log.warn <<-EOF -Please use the registry_key resource in Chef Client 11 and 12. -windows_registry will be removed in the next major version release -of the Windows cookbook. -EOF -end diff --git a/cookbooks/windows/resources/share.rb b/cookbooks/windows/resources/share.rb new file mode 100644 index 0000000..7a38087 --- /dev/null +++ b/cookbooks/windows/resources/share.rb @@ -0,0 +1,289 @@ +# -*- coding: utf-8 -*- +# +# Author:: Sölvi Páll Ásgeirsson (), Richard Lavey (richard.lavey@calastone.com) +# Cookbook:: windows +# Resource:: share +# +# Copyright:: 2014-2017, Sölvi Páll Ásgeirsson. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +property :share_name, String, name_property: true +property :path, String, required: true +property :description, String, default: '' +property :full_users, Array, default: [] +property :change_users, Array, default: [] +property :read_users, Array, default: [] + +include Windows::Helper +include Chef::Mixin::PowershellOut + +require 'win32ole' if RUBY_PLATFORM =~ /mswin|mingw32|windows/ + +ACCESS_FULL = 2_032_127 +ACCESS_CHANGE = 1_245_631 +ACCESS_READ = 1_179_817 + +action :create do + if different_path? + unless current_resource.path.nil? || current_resource.path.empty? + converge_by('Removing previous share') do + delete_share + end + end + converge_by("Creating share #{current_resource.share_name}") do + create_share + end + end + + if different_members?(:full_users) || + different_members?(:change_users) || + different_members?(:read_users) || + different_description? + converge_by("Setting permissions and description for #{new_resource.share_name}") do + set_share_permissions + end + end +end + +action :delete do + if !current_resource.path.nil? && !current_resource.path.empty? + converge_by("Deleting #{current_resource.share_name}") do + delete_share + end + else + Chef::Log.debug("#{current_resource.share_name} does not exist - nothing to do") + end +end + +load_current_value do |desired| + wmi = WIN32OLE.connect('winmgmts://') + shares = wmi.ExecQuery("SELECT * FROM Win32_Share WHERE name = '#{desired.share_name}'") + existing_share = shares.Count == 0 ? nil : shares.ItemIndex(0) + + description '' + unless existing_share.nil? + path existing_share.Path + description existing_share.Description + end + + perms = share_permissions name + unless perms.nil? + full_users perms[:full_users] + change_users perms[:change_users] + read_users perms[:read_users] + end +end + +def share_permissions(name) + wmi = WIN32OLE.connect('winmgmts://') + shares = wmi.ExecQuery("SELECT * FROM Win32_LogicalShareSecuritySetting WHERE name = '#{name}'") + + # The security descriptor is an output parameter + sd = nil + begin + shares.ItemIndex(0).GetSecurityDescriptor(sd) + sd = WIN32OLE::ARGV[0] + rescue WIN32OLERuntimeError + Chef::Log.warn('Failed to retrieve any security information about the share.') + end + + read = [] + change = [] + full = [] + + unless sd.nil? + sd.DACL.each do |dacl| + trustee = "#{dacl.Trustee.Domain}\\#{dacl.Trustee.Name}".downcase + case dacl.AccessMask + when ACCESS_FULL + full.push(trustee) + when ACCESS_CHANGE + change.push(trustee) + when ACCESS_READ + read.push(trustee) + else + Chef::Log.warn "Unknown access mask #{dacl.AccessMask} for user #{trustee}. This will be lost if permissions are updated" + end + end + end + + { + full_users: full, + change_users: change, + read_users: read, + } +end + +action_class do + def description_exists?(resource) + !resource.description.nil? + end + + def different_description? + if description_exists?(new_resource) && description_exists?(current_resource) + new_resource.description.casecmp(current_resource.description) != 0 + else + description_exists?(new_resource) || description_exists?(current_resource) + end + end + + def different_path? + return true if current_resource.path.nil? + win_friendly_path(new_resource.path).casecmp(win_friendly_path(current_resource.path)) != 0 + end + + def different_members?(permission_type) + !(current_resource.send(permission_type.to_sym) - new_resource.send(permission_type.to_sym).map(&:downcase)).empty? && + !(new_resource.send(permission_type.to_sym).map(&:downcase) - current_resource.send(permission_type.to_sym)).empty? + end + + def find_share_by_name(name) + wmi = WIN32OLE.connect('winmgmts://') + shares = wmi.ExecQuery("SELECT * FROM Win32_Share WHERE name = '#{name}'") + shares.Count == 0 ? nil : shares.ItemIndex(0) + end + + def delete_share + find_share_by_name(new_resource.share_name).delete + end + + def create_share + raise "#{new_resource.path} is missing or not a directory" unless ::File.directory? new_resource.path + new_share_script = <<-EOH + $share = [wmiclass]"\\\\#{ENV['COMPUTERNAME']}\\root\\CimV2:Win32_Share" + $result=$share.Create('#{new_resource.path}', + '#{new_resource.share_name}', + 0, + 16777216, + '#{new_resource.description}', + $null, + $null) + exit $result.returnValue + EOH + r = powershell_out new_share_script + message = case r.exitstatus + when 2 + '2 : Access Denied' + when 8 + '8 : Unknown Failure' + when 9 + '9 : Invalid Name' + when 10 + '10 : Invalid Level' + when 21 + '21 : Invalid Parameter' + when 22 + '22 : Duplicate Share' + when 23 + '23 : Redirected Path' + when 24 + '24 : Unknown Device or Directory' + when 25 + '25 : Net Name Not Found' + else + r.exitstatus.to_s + end + + raise "Could not create share. Win32_Share.create returned #{message}" if r.error? + end + + # set_share_permissions - Enforce the share permissions as dictated by the resource attributes + def set_share_permissions + share_permissions_script = <<-EOH + Function New-SecurityDescriptor + { + param ( + [array]$ACEs + ) + #Create SeCDesc object + $SecDesc = ([WMIClass] "\\\\$env:ComputerName\\root\\cimv2:Win32_SecurityDescriptor").CreateInstance() + + foreach ($ACE in $ACEs ) + { + $SecDesc.DACL += $ACE.psobject.baseobject + } + + #Return the security Descriptor + return $SecDesc + } + + Function New-ACE + { + param ( + [string] $Name, + [string] $Domain, + [string] $Permission = "Read" + ) + #Create the Trusteee Object + $Trustee = ([WMIClass] "\\\\$env:computername\\root\\cimv2:Win32_Trustee").CreateInstance() + $account = get-wmiobject Win32_Account -filter "Name like '$Name' and Domain like '$Domain'" + $accountSID = [WMI] "\\\\$env:ComputerName\\root\\cimv2:Win32_SID.SID='$($account.sid)'" + + $Trustee.Domain = $Domain + $Trustee.Name = $Name + $Trustee.SID = $accountSID.BinaryRepresentation + + #Create ACE (Access Control List) object. + $ACE = ([WMIClass] "\\\\$env:ComputerName\\root\\cimv2:Win32_ACE").CreateInstance() + switch ($Permission) + { + "Read" { $ACE.AccessMask = 1179817 } + "Change" { $ACE.AccessMask = 1245631 } + "Full" { $ACE.AccessMask = 2032127 } + default { throw "$Permission is not a supported permission value. Possible values are 'Read','Change','Full'" } + } + + $ACE.AceFlags = 3 + $ACE.AceType = 0 + $ACE.Trustee = $Trustee + + $ACE + } + + $dacl_array = @() + + EOH + new_resource.full_users.each do |user| + share_permissions_script += user_to_ace(user, 'Full') + end + + new_resource.change_users.each do |user| + share_permissions_script += user_to_ace(user, 'Change') + end + + new_resource.read_users.each do |user| + share_permissions_script += user_to_ace(user, 'Read') + end + + share_permissions_script += <<-EOH + + $dacl = New-SecurityDescriptor -Aces $dacl_array + + $share = get-wmiobject win32_share -filter 'Name like "#{new_resource.share_name}"' + $return = $share.SetShareInfo($null, '#{new_resource.description}', $dacl) + exit $return.returnValue + EOH + r = powershell_out(share_permissions_script) + raise "Could not set share permissions. Win32_Share.SedtShareInfo returned #{r.exitstatus}" if r.error? + end + + def user_to_ace(fully_qualified_user_name, access) + domain, user = fully_qualified_user_name.split('\\') + unless domain && user + raise "Invalid user entry #{fully_qualified_user_name}. The user names must be specified as 'DOMAIN\\user'" + end + "\n$dacl_array += new-ace -Name '#{user}' -domain '#{domain}' -permission '#{access}'" + end +end diff --git a/cookbooks/windows/resources/shortcut.rb b/cookbooks/windows/resources/shortcut.rb index 6b8b646..ab35f17 100644 --- a/cookbooks/windows/resources/shortcut.rb +++ b/cookbooks/windows/resources/shortcut.rb @@ -1,36 +1,53 @@ -# -# Author:: Doug MacEachern -# Cookbook Name:: windows -# Resource:: shortcut -# -# Copyright:: 2010, VMware, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -actions :create - -default_action :create - -attribute :name, kind_of: String -attribute :target, kind_of: String -attribute :arguments, kind_of: String -attribute :description, kind_of: String -attribute :cwd, kind_of: String -attribute :iconlocation, kind_of: String - -# Covers 0.10.8 and earlier -def initialize(*args) - super - @action = :create -end +# +# Author:: Doug MacEachern +# Cookbook:: windows +# Resource:: shortcut +# +# Copyright:: 2010-2017, VMware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +property :name, String +property :target, String +property :arguments, String +property :description, String +property :cwd, String +property :iconlocation, String + +load_current_value do |desired| + require 'win32ole' if RUBY_PLATFORM =~ /mswin|mingw32|windows/ + + link = WIN32OLE.new('WScript.Shell').CreateShortcut(desired.name) + name desired.name + target(link.TargetPath) + arguments(link.Arguments) + description(link.Description) + cwd(link.WorkingDirectory) + iconlocation(link.IconLocation) +end + +action :create do + converge_if_changed do + converge_by "creating shortcut #{new_resource.name}" do + link = WIN32OLE.new('WScript.Shell').CreateShortcut(new_resource.name) + link.TargetPath = new_resource.target unless new_resource.target.nil? + link.Arguments = new_resource.arguments unless new_resource.arguments.nil? + link.Description = new_resource.description unless new_resource.description.nil? + link.WorkingDirectory = new_resource.cwd unless new_resource.cwd.nil? + link.IconLocation = new_resource.iconlocation unless new_resource.iconlocation.nil? + # ignoring: WindowStyle, Hotkey + link.Save + end + end +end diff --git a/cookbooks/windows/resources/task.rb b/cookbooks/windows/resources/task.rb index 81723cb..2f3ca13 100644 --- a/cookbooks/windows/resources/task.rb +++ b/cookbooks/windows/resources/task.rb @@ -1,52 +1,384 @@ -# -# Author:: Paul Mooring () -# Cookbook Name:: windows -# Resource:: task -# -# Copyright:: 2012-2015, Chef Software, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# Passwords can't be loaded for existing tasks, making :modify both confusing -# and not very useful -actions :create, :delete, :run, :end, :change, :enable, :disable - -attribute :task_name, kind_of: String, name_attribute: true, regex: [/\A[^\/\:\*\?\<\>\|]+\z/] -attribute :command, kind_of: String -attribute :cwd, kind_of: String -attribute :user, kind_of: String, default: 'SYSTEM' -attribute :password, kind_of: String, default: nil -attribute :run_level, equal_to: [:highest, :limited], default: :limited -attribute :force, kind_of: [TrueClass, FalseClass], default: false -attribute :interactive_enabled, kind_of: [TrueClass, FalseClass], default: false -attribute :frequency_modifier, kind_of: Integer, default: 1 -attribute :frequency, equal_to: [:minute, - :hourly, - :daily, - :weekly, - :monthly, - :once, - :on_logon, - :onstart, - :on_idle], default: :hourly -attribute :start_day, kind_of: String, default: nil -attribute :start_time, kind_of: String, default: nil -attribute :day, kind_of: [String, Integer], default: nil - -attr_accessor :exists, :status, :enabled - -def initialize(name, run_context = nil) - super - @action = :create -end +# +# Author:: Paul Mooring () +# Cookbook:: windows +# Resource:: task +# +# Copyright:: 2012-2017, Chef Software, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# Passwords can't be loaded for existing tasks, making :modify both confusing +# and not very useful + +require 'chef/mixin/shell_out' +require 'rexml/document' + +include Chef::Mixin::ShellOut +include Chef::Mixin::PowershellOut + +property :task_name, String, name_property: true, regex: [/\A[^\/\:\*\?\<\>\|]+\z/] +property :command, String +property :cwd, String +property :user, String, default: 'SYSTEM' +property :password, String +property :run_level, equal_to: [:highest, :limited], default: :limited +property :force, [true, false], default: false +property :interactive_enabled, [true, false], default: false +property :frequency_modifier, [Integer, String], default: 1 +property :frequency, equal_to: [:minute, + :hourly, + :daily, + :weekly, + :monthly, + :once, + :on_logon, + :onstart, + :on_idle], default: :hourly +property :start_day, String +property :start_time, String +property :day, [String, Integer] +property :months, String +property :idle_time, Integer +property :exists, [true, false], desired_state: true +property :status, Symbol, desired_state: true +property :enabled, [true, false], desired_state: true + +def load_task_hash(task_name) + Chef::Log.debug 'Looking for existing tasks' + + # we use powershell_out here instead of powershell_out! because a failure implies that the task does not exist + task_script = <<-EOH + [Console]::OutputEncoding = [Text.UTF8Encoding]::UTF8 + schtasks /Query /FO LIST /V /TN \"#{task_name}\" + EOH + output = powershell_out(task_script).stdout.force_encoding('UTF-8') + if output.empty? + task = false + else + task = {} + + output.split("\n").map! { |line| line.split(':', 2).map!(&:strip) }.each do |field| + if field.is_a?(Array) && field[0].respond_to?(:to_sym) + task[field[0].gsub(/\s+/, '').to_sym] = field[1] + end + end + end + + task +end + +load_current_value do |desired| + pathed_task_name = desired.task_name.start_with?('\\') ? desired.task_name : "\\#{desired.task_name}" + + task_hash = load_task_hash pathed_task_name + + task_name pathed_task_name + if task_hash.respond_to?(:[]) && task_hash[:TaskName] == pathed_task_name + exists true + status :running if task_hash[:Status] == 'Running' + enabled task_hash[:ScheduledTaskState] == 'Enabled' ? true : false + cwd task_hash[:StartIn] unless task_hash[:StartIn] == 'N/A' + command task_hash[:TaskToRun] + user task_hash[:RunAsUser] + else + exists false + end +end + +action :create do + if current_resource.exists && !(task_need_update? || new_resource.force) + Chef::Log.info "#{new_resource} task already exists - nothing to do" + else + converge_by("creating a new scheduled task #{new_resource.task_name}") do + validate_user_and_password + validate_interactive_setting + validate_create_frequency_modifier + validate_create_day + validate_create_months + validate_idle_time + + options = {} + options['F'] = '' if new_resource.force || task_need_update? + options['SC'] = schedule + options['MO'] = new_resource.frequency_modifier if frequency_modifier_allowed + options['I'] = new_resource.idle_time unless new_resource.idle_time.nil? + options['SD'] = new_resource.start_day unless new_resource.start_day.nil? + options['ST'] = new_resource.start_time unless new_resource.start_time.nil? + options['TR'] = new_resource.command + options['RU'] = new_resource.user + options['RP'] = new_resource.password if use_password? + options['RL'] = 'HIGHEST' if new_resource.run_level == :highest + options['IT'] = '' if new_resource.interactive_enabled + options['D'] = new_resource.day if new_resource.day + options['M'] = new_resource.months unless new_resource.months.nil? + + run_schtasks 'CREATE', options + cwd(new_resource.cwd) if new_resource.cwd + end + end +end + +action :run do + if current_resource.exists + if current_resource.status == :running + Chef::Log.info "#{new_resource} task is currently running, skipping run" + else + converge_by("running scheduled task #{new_resource.task_name}") do + run_schtasks 'RUN' + new_resource.updated_by_last_action true + end + end + else + Chef::Log.debug "#{new_resource} task doesn't exists - nothing to do" + end +end + +action :change do + if current_resource.exists + converge_by("changing scheduled task #{new_resource.task_name}") do + validate_user_and_password + validate_interactive_setting + + options = {} + options['TR'] = new_resource.command if new_resource.command + options['RU'] = new_resource.user if new_resource.user + options['RP'] = new_resource.password if new_resource.password + options['SD'] = new_resource.start_day unless new_resource.start_day.nil? + options['ST'] = new_resource.start_time unless new_resource.start_time.nil? + options['IT'] = '' if new_resource.interactive_enabled + + run_schtasks 'CHANGE', options + cwd(new_resource.cwd) if new_resource.cwd != current_resource.cwd + end + else + Chef::Log.debug "#{new_resource} task doesn't exists - nothing to do" + end +end + +action :delete do + if current_resource.exists + converge_by("deleting scheduled task #{new_resource.task_name}") do + # always need to force deletion + run_schtasks 'DELETE', 'F' => '' + end + else + Chef::Log.debug "#{new_resource} task doesn't exists - nothing to do" + end +end + +action :end do + if current_resource.exists + if current_resource.status != :running + Chef::Log.debug "#{new_resource} is not running - nothing to do" + else + converge_by("stopping scheduled task #{new_resource.task_name}") do + run_schtasks 'END' + end + end + else + Chef::Log.fatal "#{new_resource} task doesn't exist - nothing to do" + raise Errno::ENOENT, "#{new_resource}: task does not exist, cannot end" + end +end + +action :enable do + if current_resource.exists + if current_resource.enabled + Chef::Log.debug "#{new_resource} already enabled - nothing to do" + else + converge_by("enabling scheduled task #{new_resource.task_name}") do + run_schtasks 'CHANGE', 'ENABLE' => '' + end + end + else + Chef::Log.fatal "#{new_resource} task doesn't exist - nothing to do" + raise Errno::ENOENT, "#{new_resource}: task does not exist, cannot enable" + end +end + +action :disable do + if current_resource.exists + if current_resource.enabled + converge_by("disabling scheduled task #{new_resource.task_name}") do + run_schtasks 'CHANGE', 'DISABLE' => '' + end + else + Chef::Log.debug "#{new_resource} already disabled - nothing to do" + end + else + Chef::Log.debug "#{new_resource} task doesn't exist - nothing to do" + end +end + +action_class do + # rubocop:disable Style/StringLiteralsInInterpolation + def run_schtasks(task_action, options = {}) + cmd = "schtasks /#{task_action} /TN \"#{new_resource.task_name}\" " + options.keys.each do |option| + cmd += "/#{option} " + cmd += "\"#{options[option].to_s.gsub('"', "\\\"")}\" " unless options[option] == '' + end + Chef::Log.debug('running: ') + Chef::Log.debug(" #{cmd}") + shell_out!(cmd, returns: [0]) + end + # rubocop:enable Style/StringLiteralsInInterpolation + + def task_need_update? + # gsub needed as schtasks converts single quotes to double quotes on creation + current_resource.command != new_resource.command.tr("'", '"') || + current_resource.user != new_resource.user + end + + def cwd(folder) + Chef::Log.debug 'looking for existing tasks' + + # we use shell_out here instead of shell_out! because a failure implies that the task does not exist + xml_cmd = shell_out("schtasks /Query /TN \"#{new_resource.task_name}\" /XML") + + return if xml_cmd.exitstatus != 0 + + doc = REXML::Document.new(xml_cmd.stdout) + + Chef::Log.debug 'Removing former CWD if any' + doc.root.elements.delete('Actions/Exec/WorkingDirectory') + + unless folder.nil? + Chef::Log.debug 'Setting CWD as #folder' + cwd_element = REXML::Element.new('WorkingDirectory') + cwd_element.add_text(folder) + exec_element = doc.root.elements['Actions/Exec'] + exec_element.add_element(cwd_element) + end + + temp_task_file = ::File.join(ENV['TEMP'], 'windows_task.xml') + begin + ::File.open(temp_task_file, 'w:UTF-16LE') do |f| + doc.write(f) + end + + options = {} + options['RU'] = new_resource.user if new_resource.user + options['RP'] = new_resource.password if new_resource.password + options['IT'] = '' if new_resource.interactive_enabled + options['XML'] = temp_task_file + + run_schtasks('DELETE', 'F' => '') + run_schtasks('CREATE', options) + ensure + ::File.delete(temp_task_file) + end + end + + SYSTEM_USERS = ['NT AUTHORITY\SYSTEM', 'SYSTEM', 'NT AUTHORITY\LOCALSERVICE', 'NT AUTHORITY\NETWORKSERVICE'].freeze + + def validate_user_and_password + return unless new_resource.user && use_password? + return unless new_resource.password.nil? + Chef::Log.fatal "#{new_resource.task_name}: Can't specify a non-system user without a password!" + end + + def validate_interactive_setting + return unless new_resource.interactive_enabled && new_resource.password.nil? + Chef::Log.fatal "#{new_resource} did not provide a password when attempting to set interactive/non-interactive." + end + + def validate_create_day + return unless new_resource.day + unless [:weekly, :monthly].include?(new_resource.frequency) + raise 'day attribute is only valid for tasks that run weekly or monthly' + end + return unless new_resource.day.is_a?(String) && new_resource.day.to_i.to_s != new_resource.day + days = new_resource.day.split(',') + days.each do |day| + unless ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun', '*'].include?(day.strip.downcase) + raise 'day attribute invalid. Only valid values are: MON, TUE, WED, THU, FRI, SAT, SUN and *. Multiple values must be separated by a comma.' + end + end + end + + def validate_create_months + return unless new_resource.months + unless [:monthly].include?(new_resource.frequency) + raise 'months attribute is only valid for tasks that run monthly' + end + return unless new_resource.months.is_a? String + months = new_resource.months.split(',') + months.each do |month| + unless ['JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC', '*'].include?(month.strip.upcase) + raise 'months attribute invalid. Only valid values are: JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC and *. Multiple values must be separated by a comma.' + end + end + end + + def validate_idle_time + return unless new_resource.frequency == :on_idle + return if new_resource.idle_time.to_i > 0 && new_resource.idle_time.to_i <= 999 + raise "idle_time value #{new_resource.idle_time} is invalid. Valid values for :on_idle frequency are 1 - 999." + end + + def validate_create_frequency_modifier + # Currently is handled in create action 'frequency_modifier_allowed' line. Does not allow for frequency_modifier for once,onstart,onlogon,onidle + # Note that 'OnEvent' is not a supported frequency. + return if new_resource.frequency.nil? || new_resource.frequency_modifier.nil? + case new_resource.frequency + when :minute + unless new_resource.frequency_modifier.to_i > 0 && new_resource.frequency_modifier.to_i <= 1439 + raise "frequency_modifier value #{new_resource.frequency_modifier} is invalid. Valid values for :minute frequency are 1 - 1439." + end + when :hourly + unless new_resource.frequency_modifier.to_i > 0 && new_resource.frequency_modifier.to_i <= 23 + raise "frequency_modifier value #{new_resource.frequency_modifier} is invalid. Valid values for :hourly frequency are 1 - 23." + end + when :daily + unless new_resource.frequency_modifier.to_i > 0 && new_resource.frequency_modifier.to_i <= 365 + raise "frequency_modifier value #{new_resource.frequency_modifier} is invalid. Valid values for :daily frequency are 1 - 365." + end + when :weekly + unless new_resource.frequency_modifier.to_i > 0 && new_resource.frequency_modifier.to_i <= 52 + raise "frequency_modifier value #{new_resource.frequency_modifier} is invalid. Valid values for :weekly frequency are 1 - 52." + end + when :monthly + unless ('1'..'12').to_a.push('FIRST', 'SECOND', 'THIRD', 'FOURTH', 'LAST', 'LASTDAY').include?(new_resource.frequency_modifier.to_s.upcase) + raise "frequency_modifier value #{new_resource.frequency_modifier} is invalid. Valid values for :monthly frequency are 1 - 12, 'FIRST', 'SECOND', 'THIRD', 'FOURTH', 'LAST', 'LASTDAY'." + end + end + end + + def use_password? + @use_password ||= !SYSTEM_USERS.include?(new_resource.user.upcase) + end + + def schedule + case new_resource.frequency + when :on_logon + 'ONLOGON' + when :on_idle + 'ONIDLE' + else + new_resource.frequency + end + end + + def frequency_modifier_allowed + case new_resource.frequency + when :minute, :hourly, :daily, :weekly + true + when :monthly + new_resource.months.nil? || %w(FIRST SECOND THIRD FOURTH LAST LASTDAY).include?(new_resource.frequency_modifier) + else + false + end + end +end diff --git a/cookbooks/windows/resources/zipfile.rb b/cookbooks/windows/resources/zipfile.rb index f1af3b3..cb45609 100644 --- a/cookbooks/windows/resources/zipfile.rb +++ b/cookbooks/windows/resources/zipfile.rb @@ -1,33 +1,125 @@ -# -# Author:: Doug MacEachern () -# Author:: Seth Chisamore () -# Cookbook Name:: windows -# Resource:: zipfile -# -# Copyright:: 2010, VMware, Inc. -# Copyright:: 2011-2015, Chef Software, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -actions :unzip, :zip - -attribute :path, kind_of: String, name_attribute: true -attribute :source, kind_of: String -attribute :overwrite, kind_of: [TrueClass, FalseClass], default: false -attribute :checksum, kind_of: String - -def initialize(name, run_context = nil) - super - @action = :unzip -end +# +# Author:: Doug MacEachern () +# Author:: Seth Chisamore () +# Cookbook:: windows +# Resource:: zipfile +# +# Copyright:: 2010-2017, VMware, Inc. +# Copyright:: 2011-2017, Chef Software, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +property :path, String, name_property: true +property :source, String +property :overwrite, [true, false], default: false +property :checksum, String + +include Windows::Helper +require 'find' + +action :unzip do + ensure_rubyzip_gem_installed + Chef::Log.debug("unzip #{new_resource.source} => #{new_resource.path} (overwrite=#{new_resource.overwrite})") + + cache_file_path = if new_resource.source =~ %r{^(file|ftp|http|https):\/\/} # http://rubular.com/r/DGoIWjLfGI + uri = as_uri(source) + local_cache_path = "#{Chef::Config[:file_cache_path]}/#{::File.basename(::URI.unescape(uri.path))}" + Chef::Log.debug("Caching a copy of file #{new_resource.source} at #{cache_file_path}") + + remote_file local_cache_path do + source new_resource.source + backup false + checksum new_resource.checksum unless new_resource.checksum.nil? + end + + local_cache_path + else + new_resource.source + end + + cache_file_path = win_friendly_path(cache_file_path) + + converge_by("unzip #{new_resource.source}") do + ruby_block 'Unzipping' do + block do + Zip::File.open(cache_file_path) do |zip| + zip.each do |entry| + path = ::File.join(new_resource.path, entry.name) + FileUtils.mkdir_p(::File.dirname(path)) + if new_resource.overwrite && ::File.exist?(path) && !::File.directory?(path) + FileUtils.rm(path) + end + zip.extract(entry, path) unless ::File.exist?(path) + end + end + end + action :run + end + end +end + +action :zip do + ensure_rubyzip_gem_installed + # sanitize paths for windows. + new_resource.source.downcase.gsub!(::File::SEPARATOR, ::File::ALT_SEPARATOR) + new_resource.path.downcase.gsub!(::File::SEPARATOR, ::File::ALT_SEPARATOR) + Chef::Log.debug("zip #{new_resource.source} => #{new_resource.path} (overwrite=#{new_resource.overwrite})") + + if new_resource.overwrite == false && ::File.exist?(new_resource.path) + Chef::Log.info("file #{new_resource.path} already exists and overwrite is set to false, exiting") + else + # delete the archive if it already exists, because we are recreating it. + if ::File.exist?(new_resource.path) + converge_by("delete existing file at #{new_resource.path}") do + ::File.unlink(new_resource.path) + end + end + + # only supporting compression of a single directory (recursively). + if ::File.directory?(new_resource.source) + converge_by("zipping #{new_resource.source} to #{new_resource.path}") do + z = Zip::File.new(new_resource.path, true) + unless new_resource.source =~ /::File::ALT_SEPARATOR$/ + new_resource.source << ::File::ALT_SEPARATOR + end + Find.find(new_resource.source) do |f| + f.downcase.gsub!(::File::SEPARATOR, ::File::ALT_SEPARATOR) + # don't add root directory to the zipfile. + next if f == new_resource.source + # strip the root directory from the filename before adding it to the zipfile. + zip_fname = f.sub(new_resource.source, '') + Chef::Log.debug("adding #{zip_fname} to archive, sourcefile is: #{f}") + z.add(zip_fname, f) + end + z.close + end + else + Chef::Log.info("Single directory must be specified for compression, and #{new_resource.source} does not meet that criteria.") + end + end +end + +action_class do + def ensure_rubyzip_gem_installed + require 'zip' + rescue LoadError + Chef::Log.info("Missing gem 'rubyzip'...installing now.") + chef_gem 'rubyzip' do + version node['windows']['rubyzipversion'] + action :install + compile_time true + end + require 'zip' + end +end diff --git a/cookbooks/xml/CHANGELOG.md b/cookbooks/xml/CHANGELOG.md index 69caa07..c0dedd4 100644 --- a/cookbooks/xml/CHANGELOG.md +++ b/cookbooks/xml/CHANGELOG.md @@ -1,14 +1,41 @@ # xml Cookbook CHANGELOG + This file is used to list changes made in each version of the xml cookbook. +## 3.1.2 (2017-05-30) + +- Fix Amazon linux support on Chef 13 + +## 3.1.1 (2017-01-16) + +- Use the right priority to set compile_time attribute + +## 3.1.0 (2016-12-07) + +- Move the build essential compile time setting to attributes file +- Remove the Chef 11 compatibility check in chef_gem +- Remove support for Arch since it's not a supported Chef platform +- If no packages are defined log a warning instead of failing hard +- Add specs for all supported platforms and windows + +## 3.0.0 (2016-09-07) + +- Make sure to install zlib-devel on RHEL +- Testing updates +- Require Chef 12.1 and use multipackage to speed up installs +- Don't use chef-sugar since it wasn't necessary + ## v2.0.0 (2015-12-07) -- The 1.3.1 release pinned the nokogiri gem version to 1.6.2.1 to avoid compilation failure that occured at some point in time. The cookbook also prevented the user from setting the version attribute to a modern nokogiri release. Nokogiri no longer fails to install so there is no longer a reason to pin or gate the versions. This release removes the version attribute and instead installs the latest version, but still allows the user to set the version attribute to pin to a specific version. + +- The 1.3.1 release pinned the nokogiri gem version to 1.6.2.1 to avoid compilation failure that occured at some point in time. The cookbook also prevented the user from setting the version attribute to a modern nokogiri release. Nokogiri no longer fails to install so there is no longer a reason to pin or gate the versions. This release removes the version attribute and instead installs the latest version, but still allows the user to set the version attribute to pin to a specific version. ## v1.3.1 (2015-10-12) + - Fixed compile errors on Chef 11 - Added an empty array of packages for unknown systems to prevent failures on Windows and other operating systems ## v1.3.0 (2015-10-06) + - Added zlib1g-dev on Ubuntu / Debian to fix compiles - Add support for OS X - Add source_url and issues_url to metadata.rb for Supermarket @@ -29,53 +56,70 @@ This file is used to list changes made in each version of the xml cookbook. - Update .gitignore and add chefignore to prevent extra files from being uploaded to the Chef server ## v1.2.13 (2014-02-18) + - Reverting compile_time work ## v1.2.12 (2014-02-18) + - Fixing last patch to play nicely with Chef Sugar ## v1.2.11 (2014-02-18) + - Fixing chef_gem for Chef below 12.1.0 ## v1.2.10 (2014-02-17) + - Being explicit about usage of the chef_gem's compile_time property. - Eliminating future deprecation warnings in Chef 12.1.0. ## v1.2.9 (2014-12-10) + - Re-release with stove 3.2.2 to get a metadata.rb ## v1.2.8 (2014-12-09) + - [#11] Fix warning message from build-essential - [#13] pin nokogiri to a working version ## v1.2.6 (2014-06-17) + - [COOK-4468] Only set ENV variable when needed ## v1.2.4 (2014-03-27) + - [COOK-4474] - Bump apt and yum versions in Berksfile, Lock to build-essentials 1.4 - [COOK-4468] - Set NOKOGIRI_USE_SYSTEM_LIBRARIES env variable ## v1.2.2 (2014-02-27) + [COOK-4382] - Fix xml cookbook spec test [COOK-4304] - Set proper packages for SUSE 11 ## v1.2.1 + ### Improvement + - [COOK-4304](https://tickets.chef.io/browse/COOK-4304) - Now sets proper packages for SUSE 11 ## v1.2.0 + ### Improvement + - **[COOK-3462](https://tickets.chef.io/browse/COOK-3462)** - Allow installing packages during compile time ## v1.1.2 + - [COOK-2059] - missing dependency on build-essential ## v1.1.0 + - [COOK-1826] - support nokogiri chef_gem - [COOK-1902] - add support for archlinux ## v1.0.4 + - [COOK-1232] - add xslt to xml cookbook ## v1.0.2 + - [COOK-953] - Add FreeBSD support - [COOK-775] - Add Amazon Linux support diff --git a/cookbooks/xml/MAINTAINERS.md b/cookbooks/xml/MAINTAINERS.md index c6a51ae..645ed14 100644 --- a/cookbooks/xml/MAINTAINERS.md +++ b/cookbooks/xml/MAINTAINERS.md @@ -1,19 +1,15 @@ # Maintainers -This file lists how this cookbook project is maintained. When making changes to the system, this -file tells you who needs to review your patch - you need a simple majority of maintainers -for the relevant subsystems to provide a :+1: on your pull request. Additionally, you need -to not receive a veto from a Lieutenant or the Project Lead. -Check out [How Cookbooks are Maintained](https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/CONTRIBUTING.MD) -for details on the process and how to become a maintainer or the project lead. +This file lists how this cookbook project is maintained. When making changes to the system, this file tells you who needs to review your patch - you need a review from an existing maintainer for the cookbook to provide a :+1: on your pull request. Additionally, you need to not receive a veto from a Lieutenant or the Project Lead. + +Check out [How Cookbooks are Maintained](https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/CONTRIBUTING.MD) for details on the process and how to become a maintainer or the project lead. # Project Maintainer * [Tim Smith](https://github.com/tas50) # Maintainers * [Jennifer Davis](https://github.com/sigje) -* [Sean OMeara](https://github.com/someara) * [Tim Smith](https://github.com/tas50) * [Thom May](https://github.com/thommay) diff --git a/cookbooks/xml/README.md b/cookbooks/xml/README.md index 3d11548..6270dd0 100644 --- a/cookbooks/xml/README.md +++ b/cookbooks/xml/README.md @@ -1,45 +1,57 @@ # XML Cookbook + [![Build Status](https://travis-ci.org/chef-cookbooks/xml.svg?branch=master)](http://travis-ci.org/chef-cookbooks/xml) [![Cookbook Version](http://img.shields.io/cookbook/v/xml.svg)](https://supermarket.chef.io/cookbooks/xml) Installs development package for libxml. +## DEPRECATED + +nokogiri is now included in Chef so this cookbook has been deprecated. If a more useful purpose can be come up with for the namespace we will gladly revive it + ## Requirements + ### Platforms + - Debian/Ubuntu - RHEL/CentOS/Scientific/Amazon/Oracle -- Arch Linux - Suse - FreeBSD ### Chef -- Chef 11+ + +- Chef 12.1+ ### Cookbooks + - build-essential -- chef-sugar ## Attributes + - `node['xml']['packages']` - Array of package names that should be installed - `node['xml']['nokogiri']['use_system_libraries']` - Whether to use system libraries for nokogiri (defaults to `false`) ## Recipes + ### default + Installs the development packages for libxml2 and libxslt. For installing the packages during compile time: ```ruby -node.set['xml']['compiletime'] = true +node.normal['xml']['compiletime'] = true include_recipe 'xml::default' ``` ### ruby -Installs the nokogiri gem into Chef's Ruby environment so it can be used in recipes. If nokogiri is being installed using the system's libxml package your distro must include version 2.6.21 or later. Due to this Debian 7 or earlier / Ubuntu 12.04 or earlier will not work with the system library attribute enabled. + +Installs the nokogiri gem into Chef's Ruby environment so it can be used in recipes. If nokogiri is being installed using the system's libxml package your distro must include version 2.6.21 or later. Due to this Debian 7 or earlier / Ubuntu 12.04 or earlier will not work with the system library attribute enabled. ## License & Authors + **Author:** Cookbook Engineering Team ([cookbooks@chef.io](mailto:cookbooks@chef.io)) -**Copyright:** 2009-2015, Chef Software, Inc. +**Copyright:** 2009-2016, Chef Software, Inc. ``` Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/cookbooks/xml/attributes/default.rb b/cookbooks/xml/attributes/default.rb index 6728d0f..3ea5a3c 100644 --- a/cookbooks/xml/attributes/default.rb +++ b/cookbooks/xml/attributes/default.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: xml +# Cookbook:: xml # Attributes:: default # -# Copyright 2009-2015, Chef Software, Inc. +# Copyright:: 2009-2017, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -20,11 +20,11 @@ default['xml']['compiletime'] = false case node['platform_family'] -when 'rhel', 'fedora', 'suse' - default['xml']['packages'] = %w(libxml2-devel libxslt-devel) +when 'rhel', 'fedora', 'suse', 'amazon' + default['xml']['packages'] = %w(libxml2-devel libxslt-devel zlib-devel) when 'debian' default['xml']['packages'] = %w(libxml2-dev libxslt-dev zlib1g-dev) -when 'freebsd', 'arch' +when 'freebsd' default['xml']['packages'] = %w(libxml2 libxslt) when 'mac_os_x' default['xml']['packages'] = %w(libxml2) diff --git a/cookbooks/xml/attributes/ruby.rb b/cookbooks/xml/attributes/ruby.rb new file mode 100644 index 0000000..918601f --- /dev/null +++ b/cookbooks/xml/attributes/ruby.rb @@ -0,0 +1 @@ +default['build-essential']['compile_time'] = true diff --git a/cookbooks/xml/metadata.json b/cookbooks/xml/metadata.json index c83418b..3f6f21e 100644 --- a/cookbooks/xml/metadata.json +++ b/cookbooks/xml/metadata.json @@ -1 +1 @@ -{"name":"xml","version":"2.0.0","description":"Installs xml","long_description":"# XML Cookbook\n[![Build Status](https://travis-ci.org/chef-cookbooks/xml.svg?branch=master)](http://travis-ci.org/chef-cookbooks/xml) [![Cookbook Version](http://img.shields.io/cookbook/v/xml.svg)](https://supermarket.chef.io/cookbooks/xml)\n\nInstalls development package for libxml.\n\n## Requirements\n### Platforms\n- Debian/Ubuntu\n- RHEL/CentOS/Scientific/Amazon/Oracle\n- Arch Linux\n- Suse\n- FreeBSD\n\n### Chef\n- Chef 11+\n\n### Cookbooks\n- build-essential\n- chef-sugar\n\n## Attributes\n- `node['xml']['packages']` - Array of package names that should be installed\n- `node['xml']['nokogiri']['use_system_libraries']` - Whether to use system libraries for nokogiri (defaults to `false`)\n\n## Recipes\n### default\nInstalls the development packages for libxml2 and libxslt.\n\nFor installing the packages during compile time:\n\n```ruby\nnode.set['xml']['compiletime'] = true\ninclude_recipe 'xml::default'\n```\n\n### ruby\nInstalls the nokogiri gem into Chef's Ruby environment so it can be used in recipes. If nokogiri is being installed using the system's libxml package your distro must include version 2.6.21 or later. Due to this Debian 7 or earlier / Ubuntu 12.04 or earlier will not work with the system library attribute enabled.\n\n## License & Authors\n**Author:** Cookbook Engineering Team ([cookbooks@chef.io](mailto:cookbooks@chef.io))\n\n**Copyright:** 2009-2015, Chef Software, Inc.\n\n```\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```\n","maintainer":"Chef Software, Inc.","maintainer_email":"cookbooks@chef.io","license":"Apache 2.0","platforms":{"amazon":">= 0.0.0","arch":">= 0.0.0","centos":">= 0.0.0","debian":">= 0.0.0","fedora":">= 0.0.0","freebsd":">= 0.0.0","oracle":">= 0.0.0","redhat":">= 0.0.0","scientific":">= 0.0.0","suse":">= 0.0.0","ubuntu":">= 0.0.0"},"dependencies":{"build-essential":">= 0.0.0","chef-sugar":">= 0.0.0"},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{"xml":"Installs libxml development packages"}} \ No newline at end of file +{"name":"xml","version":"3.1.2","description":"Installs xml","long_description":"# XML Cookbook\n\n[![Build Status](https://travis-ci.org/chef-cookbooks/xml.svg?branch=master)](http://travis-ci.org/chef-cookbooks/xml) [![Cookbook Version](http://img.shields.io/cookbook/v/xml.svg)](https://supermarket.chef.io/cookbooks/xml)\n\nInstalls development package for libxml.\n\n## DEPRECATED\n\nnokogiri is now included in Chef so this cookbook has been deprecated. If a more useful purpose can be come up with for the namespace we will gladly revive it\n\n## Requirements\n\n### Platforms\n\n- Debian/Ubuntu\n- RHEL/CentOS/Scientific/Amazon/Oracle\n- Suse\n- FreeBSD\n\n### Chef\n\n- Chef 12.1+\n\n### Cookbooks\n\n- build-essential\n\n## Attributes\n\n- `node['xml']['packages']` - Array of package names that should be installed\n- `node['xml']['nokogiri']['use_system_libraries']` - Whether to use system libraries for nokogiri (defaults to `false`)\n\n## Recipes\n\n### default\n\nInstalls the development packages for libxml2 and libxslt.\n\nFor installing the packages during compile time:\n\n```ruby\nnode.normal['xml']['compiletime'] = true\ninclude_recipe 'xml::default'\n```\n\n### ruby\n\nInstalls the nokogiri gem into Chef's Ruby environment so it can be used in recipes. If nokogiri is being installed using the system's libxml package your distro must include version 2.6.21 or later. Due to this Debian 7 or earlier / Ubuntu 12.04 or earlier will not work with the system library attribute enabled.\n\n## License & Authors\n\n**Author:** Cookbook Engineering Team ([cookbooks@chef.io](mailto:cookbooks@chef.io))\n\n**Copyright:** 2009-2016, Chef Software, Inc.\n\n```\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```\n","maintainer":"Chef Software, Inc.","maintainer_email":"cookbooks@chef.io","license":"Apache-2.0","platforms":{"amazon":">= 0.0.0","centos":">= 0.0.0","debian":">= 0.0.0","fedora":">= 0.0.0","freebsd":">= 0.0.0","oracle":">= 0.0.0","redhat":">= 0.0.0","scientific":">= 0.0.0","suse":">= 0.0.0","ubuntu":">= 0.0.0"},"dependencies":{"build-essential":">= 0.0.0"},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{"xml":"Installs libxml development packages"},"source_url":"https://github.com/chef-cookbooks/xml","issues_url":"https://github.com/chef-cookbooks/xml/issues","chef_version":[[">= 12.1"]],"ohai_version":[]} \ No newline at end of file diff --git a/cookbooks/xml/recipes/default.rb b/cookbooks/xml/recipes/default.rb index 0eae8a7..470b974 100644 --- a/cookbooks/xml/recipes/default.rb +++ b/cookbooks/xml/recipes/default.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: xml +# Cookbook:: xml # Recipe:: default # -# Copyright 2010-2015, Chef Software, Inc. +# Copyright:: 2010-2017, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,8 +17,10 @@ # limitations under the License. # -node['xml']['packages'].each do |pkg| - r = package pkg do +if node['xml']['packages'].empty? + Chef::Log.warn("No XML packages defined for installation in node['xml']['packages'] for your platform.") +else + r = package node['xml']['packages'] do action(node['xml']['compiletime'] ? :nothing : :install) end r.run_action(:install) if node['xml']['compiletime'] diff --git a/cookbooks/xml/recipes/ruby.rb b/cookbooks/xml/recipes/ruby.rb index 988378b..029f8ec 100644 --- a/cookbooks/xml/recipes/ruby.rb +++ b/cookbooks/xml/recipes/ruby.rb @@ -1,10 +1,10 @@ # -# Cookbook Name:: xml +# Cookbook:: xml # Recipe:: ruby # # Author:: Joseph Holsten () # -# Copyright 2008-2013, Chef Software, Inc. +# Copyright:: 2008-2017, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -19,14 +19,11 @@ # limitations under the License. # -include_recipe 'chef-sugar' - execute 'apt-get update' do ignore_failure true action :nothing end.run_action(:run) if 'debian' == node['platform_family'] -node.default['build-essential']['compile_time'] = true node.default['xml']['compiletime'] = true include_recipe 'build-essential::default' include_recipe 'xml::default' @@ -38,5 +35,5 @@ end chef_gem 'nokogiri' do version node['xml']['nokogiri']['version'] if node['xml']['nokogiri']['version'] action :install - compile_time true if defined? compile_time + compile_time true end diff --git a/cookbooks/yum-mysql-community/CHANGELOG.md b/cookbooks/yum-mysql-community/CHANGELOG.md new file mode 100644 index 0000000..bfaf1db --- /dev/null +++ b/cookbooks/yum-mysql-community/CHANGELOG.md @@ -0,0 +1,118 @@ +# yum-mysql-community Cookbook CHANGELOG + +This file is used to list changes made in each version of the yum-mysql-community cookbook. + +## 2.1.0 (2017-03-26) + +- Fix URLs for amazon so that 2017 resolves to '6' rather than 'latest' + +## 2.0.3 (2016-12-22) + +- Depend on the latest compat_resource cookbook +- Cookstyle fixes + +## 2.0.2 (2016-11-26) +- Remove yum-epel from the readme +- Switch to inspec for testing +- Fix mysql55 in travis + +## 2.0.1 (2016-11-07) +- yum_repository mirrorlist value updated in Readme + +## 2.0.0 (2016-11-05) +- Replace yum dependency with compat_resource +- Replace 'epel' with 'mysql-community' in the readme + +## 1.0.0 (2016-09-06) +- Testing updates +- Remove support for Chef 11 + +## v0.3.0 (2016-07-22) + +- Support Oracle Linux +- Correctly state the required yum cookbook version in the readme +- Add chef_version metadata to metadata.rb + +## v0.2.0 (2016-03-29) + +- Add support for the 2016 Amazon Linux releases +- Update test dependency gems and remove Guard +- Test in Travis CI using kitchen-dokken + +## v0.1.21 (2015-12-01) + +- Fixing if/unless logic in recipes + +## v0.1.20 (2015-11-30) + +- Fixed attributes with a false value not being passed + +## v0.1.19 (2015-10-28) + +- Fixing Chef 13 nil property deprecation warnings + +## v0.1.18 (2015-09-21) + +- Added Travis CI config for lint and unit testing +- Added Chef standard Rubocop file and resolved all warnings +- Added Chef standard chefignore and .gitignore files +- Add supported platforms to the metadata +- Added source_url and issues_url to the metadata +- Added long_description to the metadata +- Updated and expanded development dependencies in the Gemfile +- Added contributing, testing, and maintainers docs +- Added platform requirements to the readme +- Added Travis and cookbook version badges to the readme +- Update Chefspec to 4.X format + +## v0.1.17 (2015-04-06) + +- Updating pubkey link from someara to chef-client github orgs + +## v0.1.16 (2015-03-25) + +- Adding support Amazon Linux 2015.03 to all channels + +## v0.1.15 (2015-03-25) + +- Added support for amazon linux 2015.03 + +## v0.1.14 (2015-03-12) + +- The content of 0.1.13 is questionable: didn't have changelog entry, may have had merged attribute change, but let's be clear and say at least this version 0.1.14 is the right thing. + +## v0.1.13 (2015-03-12) + +- 3 corrected typo in public key attribute + +## v0.1.12 (2015-01-20) + +- Minor style updates + +## v0.1.11 (2014-07-21) + +- Adding RHEL-7 support + +## v0.1.10 (2014-07-21) + +- Adding mysql-5.7 and centos 7 support + +## v0.1.8 (2014-06-18) + +- Updating to support real RHEL + +## v0.1.6 (2014-06-16) + +Fixing typo in mysql55-community attributes + +## v0.1.4 (2014-06-13) + +- updating url to keys in cookbook attributes + +## v0.1.2 (2014-06-11) + +- Move files/mysql_pubkey.asc to files/default/mysql_pubkey.asc + +## v0.1.0 (2014-04-30) + +Initial release diff --git a/cookbooks/database/TESTING.md b/cookbooks/yum-mysql-community/CONTRIBUTING.md similarity index 72% rename from cookbooks/database/TESTING.md rename to cookbooks/yum-mysql-community/CONTRIBUTING.md index ca524ab..ef2f2b8 100644 --- a/cookbooks/database/TESTING.md +++ b/cookbooks/yum-mysql-community/CONTRIBUTING.md @@ -1,2 +1,2 @@ Please refer to -https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/TESTING.MD +https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/CONTRIBUTING.MD diff --git a/cookbooks/chef_handler/MAINTAINERS.md b/cookbooks/yum-mysql-community/MAINTAINERS.md similarity index 54% rename from cookbooks/chef_handler/MAINTAINERS.md rename to cookbooks/yum-mysql-community/MAINTAINERS.md index c6a51ae..ca46dbc 100644 --- a/cookbooks/chef_handler/MAINTAINERS.md +++ b/cookbooks/yum-mysql-community/MAINTAINERS.md @@ -1,16 +1,13 @@ # Maintainers -This file lists how this cookbook project is maintained. When making changes to the system, this -file tells you who needs to review your patch - you need a simple majority of maintainers -for the relevant subsystems to provide a :+1: on your pull request. Additionally, you need -to not receive a veto from a Lieutenant or the Project Lead. -Check out [How Cookbooks are Maintained](https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/CONTRIBUTING.MD) -for details on the process and how to become a maintainer or the project lead. +This file lists how this cookbook project is maintained. When making changes to the system, this file tells you who needs to review your patch - you need a review from an existing maintainer for the cookbook to provide a :+1: on your pull request. Additionally, you need to not receive a veto from a Lieutenant or the Project Lead. + +Check out [How Cookbooks are Maintained](https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/CONTRIBUTING.MD) for details on the process and how to become a maintainer or the project lead. # Project Maintainer -* [Tim Smith](https://github.com/tas50) +* [Sean OMeara](https://github.com/someara) # Maintainers * [Jennifer Davis](https://github.com/sigje) diff --git a/cookbooks/yum-mysql-community/README.md b/cookbooks/yum-mysql-community/README.md new file mode 100644 index 0000000..7bb8f85 --- /dev/null +++ b/cookbooks/yum-mysql-community/README.md @@ -0,0 +1,140 @@ +# yum-mysql-community Cookbook + +[![Build Status](https://travis-ci.org/chef-cookbooks/yum-mysql-community.svg?branch=master)](http://travis-ci.org/chef-cookbooks/yum-mysql-community) [![Cookbook Version](https://img.shields.io/cookbook/v/yum-mysql-community.svg)](https://supermarket.chef.io/cookbooks/yum-mysql-community) + +The yum-mysql-community cookbook takes over management of the default repository ids shipped with mysql*-community-release. It allows attribute manipulation of `mysql-connectors-community`, `mysql56-community`, and `mysql57-community-dmr`. + +## Requirements + +### Platforms + +- RHEL/CentOS and derivatives +- Fedora + +### Chef + +- Chef 12.1+ + +### Cookbooks + +- compat_resource + +## Attributes + +The following attributes are set by default + +```ruby +default['yum']['mysql-connectors-community']['repositoryid'] = 'mysql-connectors-community' +default['yum']['mysql-connectors-community']['description'] = 'MySQL Connectors Community' +default['yum']['mysql-connectors-community']['baseurl'] = 'http://repo.mysql.com/yum/mysql-connectors-community/el/$releasever/$basearch/' +default['yum']['mysql-connectors-community']['gpgkey'] = 'https://raw.githubusercontent.com/rs-services/equinix-public/master/cookbooks/db_mysql/files/centos/mysql_pubkey.asc' +default['yum']['mysql-connectors-community']['failovermethod'] = 'priority' +default['yum']['mysql-connectors-community']['gpgcheck'] = true +default['yum']['mysql-connectors-community']['enabled'] = true +``` + +```ruby +default['yum']['mysql56-community']['repositoryid'] = 'mysql56-community' +default['yum']['mysql56-community']['description'] = 'MySQL 5.6 Community Server' +default['yum']['mysql56-community']['baseurl'] = 'http://repo.mysql.com/yum/mysql56-community/el/$releasever/$basearch/' +default['yum']['mysql56-community']['gpgkey'] = 'https://raw.githubusercontent.com/rs-services/equinix-public/master/cookbooks/db_mysql/files/centos/mysql_pubkey.asc' +default['yum']['mysql56-community']['failovermethod'] = 'priority' +default['yum']['mysql56-community']['gpgcheck'] = true +default['yum']['mysql56-community']['enabled'] = true +``` + +```ruby +default['yum']['mysql57-community-dmr']['repositoryid'] = 'mysql57-community-dmr' +default['yum']['mysql57-community-dmr']['description'] = 'MySQL 5.7 Community Server Development Milestone Release' +default['yum']['mysql57-community-dmr']['baseurl'] = 'http://repo.mysql.com/yum/mysql56-community/el/$releasever/$basearch/' +default['yum']['mysql57-community-dmr']['gpgkey'] = 'https://raw.githubusercontent.com/rs-services/equinix-public/master/cookbooks/db_mysql/files/centos/mysql_pubkey.asc' +default['yum']['mysql57-community-dmr']['failovermethod'] = 'priority' +default['yum']['mysql57-community-dmr']['gpgcheck'] = true +default['yum']['mysql57-community-dmr']['enabled'] = true +``` + +## Recipes + +- mysql55 - Sets up the mysql56-community repository on supported +- platforms + +```ruby + yum_repository 'mysql55-community' do + mirrorlist 'https://repo.mysql.com/yum/mysql-5.5-community/el/$releasever/$basearch/' + description '' + enabled true + gpgcheck true + end +``` + +- mysql56 - Sets up the mysql56-community repository on supported +- platforms + +```ruby + yum_repository 'mysql56-community' do + mirrorlist 'https://repo.mysql.com/yum/mysql-5.6-community/el/$releasever/$basearch/' + description '' + enabled true + gpgcheck true + end +``` + +- connectors - Sets up the mysql-connectors-community repository on supported +- platforms + +## Usage Example + +To disable the mysql-community-dmr repository through a Role or Environment definition + +```ruby +default_attributes( + :yum => { + :mysql57-community-dmr => { + :enabled => { + false + } + } + } + ) +``` + +Uncommonly used repositoryids are not managed by default. This is speeds up integration testing pipelines by avoiding yum-cache builds that nobody cares about. To enable the mysql-community-dmr repository with a wrapper cookbook, place the following in a recipe: + +```ruby +node.default['yum']['mysql57-community-dmr']['enabled'] = true +node.default['yum']['mysql57-community-dmr']['managed'] = true +include_recipe 'mysql57-community-dmr' +``` + +## More Examples + +Point the mysql56-community repositories at an internally hosted server. + +``` +node.default['yum']['mysql56-community']['enabled'] = true +node.default['yum']['mysql56-community']['mirrorlist'] = nil +node.default['yum']['mysql56-community']['baseurl'] = 'https://internal.example.com/mysql/mysql56-community/' +node.default['yum']['mysql56-community']['sslverify'] = false + +include_recipe 'mysql56-community' +``` + +## License & Authors + +**Author:** Cookbook Engineering Team ([cookbooks@chef.io](mailto:cookbooks@chef.io)) + +**Copyright:** 2011-2016, Chef Software, Inc. + +``` +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +``` diff --git a/cookbooks/yum-mysql-community/attributes/mysql-connectors-community.rb b/cookbooks/yum-mysql-community/attributes/mysql-connectors-community.rb new file mode 100644 index 0000000..e76198e --- /dev/null +++ b/cookbooks/yum-mysql-community/attributes/mysql-connectors-community.rb @@ -0,0 +1,28 @@ +default['yum']['mysql-connectors-community']['repositoryid'] = 'mysql-connectors-community' +default['yum']['mysql-connectors-community']['gpgkey'] = 'https://raw.githubusercontent.com/chef-cookbooks/yum-mysql-community/master/files/default/mysql_pubkey.asc' +default['yum']['mysql-connectors-community']['description'] = 'MySQL Connectors Community' +default['yum']['mysql-connectors-community']['failovermethod'] = 'priority' +default['yum']['mysql-connectors-community']['gpgcheck'] = true +default['yum']['mysql-connectors-community']['enabled'] = true + +case node['platform_family'] +when 'rhel' + case node['platform'] + when 'amazon' + default['yum']['mysql-connectors-community']['baseurl'] = 'http://repo.mysql.com/yum/mysql-connectors-community/el/6/$basearch/' + when 'redhat', 'oracle' # ~FC024 + case node['platform_version'].to_i + when 5 + # Real Redhat identifies $releasever as 5Server and 6Server + default['yum']['mysql-connectors-community']['baseurl'] = 'http://repo.mysql.com/yum/mysql-connectors-community/el/5/$basearch/' + when 6 + default['yum']['mysql-connectors-community']['baseurl'] = 'http://repo.mysql.com/yum/mysql-connectors-community/el/6/$basearch/' + when 7 + default['yum']['mysql-connectors-community']['baseurl'] = 'http://repo.mysql.com/yum/mysql-connectors-community/el/7/$basearch/' + end + else # other rhel + default['yum']['mysql-connectors-community']['baseurl'] = 'http://repo.mysql.com/yum/mysql-connectors-community/el/$releasever/$basearch/' + end +when 'fedora' + default['yum']['mysql-connectors-community']['baseurl'] = 'http://repo.mysql.com/yum/mysql-connectors-community/fc/$releasever/$basearch/' +end diff --git a/cookbooks/yum-mysql-community/attributes/mysql55-community.rb b/cookbooks/yum-mysql-community/attributes/mysql55-community.rb new file mode 100644 index 0000000..41dbb27 --- /dev/null +++ b/cookbooks/yum-mysql-community/attributes/mysql55-community.rb @@ -0,0 +1,26 @@ +default['yum']['mysql55-community']['repositoryid'] = 'mysql55-community' +default['yum']['mysql55-community']['gpgkey'] = 'https://raw.githubusercontent.com/chef-cookbooks/yum-mysql-community/master/files/default/mysql_pubkey.asc' +default['yum']['mysql55-community']['description'] = 'MySQL 5.5 Community Server' +default['yum']['mysql55-community']['failovermethod'] = 'priority' +default['yum']['mysql55-community']['gpgcheck'] = true +default['yum']['mysql55-community']['enabled'] = true + +case node['platform_family'] +when 'rhel' + case node['platform'] + when 'amazon' + default['yum']['mysql55-community']['baseurl'] = 'http://repo.mysql.com/yum/mysql-5.5-community/el/6/$basearch/' + when 'redhat', 'oracle' # ~FC024 + case node['platform_version'].to_i + when 5 + # Real Redhat identifies $releasever as 5Server and 6Server + default['yum']['mysql55-community']['baseurl'] = 'http://repo.mysql.com/yum/mysql-5.5-community/el/5/$basearch/' + when 6 + default['yum']['mysql55-community']['baseurl'] = 'http://repo.mysql.com/yum/mysql-5.5-community/el/6/$basearch/' + when 7 + default['yum']['mysql55-community']['baseurl'] = 'http://repo.mysql.com/yum/mysql-5.5-community/el/7/$basearch/' + end + else # other rhel. only 6 and 7 for now + default['yum']['mysql55-community']['baseurl'] = 'http://repo.mysql.com/yum/mysql-5.5-community/el/$releasever/$basearch/' + end +end diff --git a/cookbooks/yum-mysql-community/attributes/mysql56-community.rb b/cookbooks/yum-mysql-community/attributes/mysql56-community.rb new file mode 100644 index 0000000..771151d --- /dev/null +++ b/cookbooks/yum-mysql-community/attributes/mysql56-community.rb @@ -0,0 +1,28 @@ +default['yum']['mysql56-community']['repositoryid'] = 'mysql56-community' +default['yum']['mysql56-community']['gpgkey'] = 'https://raw.githubusercontent.com/chef-cookbooks/yum-mysql-community/master/files/default/mysql_pubkey.asc' +default['yum']['mysql56-community']['description'] = 'MySQL 5.6 Community Server' +default['yum']['mysql56-community']['failovermethod'] = 'priority' +default['yum']['mysql56-community']['gpgcheck'] = true +default['yum']['mysql56-community']['enabled'] = true + +case node['platform_family'] +when 'rhel' + case node['platform'] + when 'amazon' + default['yum']['mysql56-community']['baseurl'] = 'http://repo.mysql.com/yum/mysql-5.6-community/el/6/$basearch/' + when 'redhat', 'oracle' # ~FC024 + case node['platform_version'].to_i + when 5 + # Real Redhat identifies $releasever as 5Server and 6Server + default['yum']['mysql56-community']['baseurl'] = 'http://repo.mysql.com/yum/mysql-5.6-community/el/5/$basearch/' + when 6 + default['yum']['mysql56-community']['baseurl'] = 'http://repo.mysql.com/yum/mysql-5.6-community/el/6/$basearch/' + when 7 + default['yum']['mysql56-community']['baseurl'] = 'http://repo.mysql.com/yum/mysql-5.6-community/el/7/$basearch/' + end + else # other rhel + default['yum']['mysql56-community']['baseurl'] = 'http://repo.mysql.com/yum/mysql-5.6-community/el/$releasever/$basearch/' + end +when 'fedora' + default['yum']['mysql56-community']['baseurl'] = 'http://repo.mysql.com/yum/mysql-5.6-community/fc/$releasever/$basearch/' +end diff --git a/cookbooks/yum-mysql-community/attributes/mysql57-community.rb b/cookbooks/yum-mysql-community/attributes/mysql57-community.rb new file mode 100644 index 0000000..997bcb0 --- /dev/null +++ b/cookbooks/yum-mysql-community/attributes/mysql57-community.rb @@ -0,0 +1,28 @@ +default['yum']['mysql57-community']['repositoryid'] = 'mysql57-community' +default['yum']['mysql57-community']['gpgkey'] = 'https://raw.githubusercontent.com/chef-cookbooks/yum-mysql-community/master/files/default/mysql_pubkey.asc' +default['yum']['mysql57-community']['description'] = 'MySQL 5.7 Community Server' +default['yum']['mysql57-community']['failovermethod'] = 'priority' +default['yum']['mysql57-community']['gpgcheck'] = true +default['yum']['mysql57-community']['enabled'] = true + +case node['platform_family'] +when 'rhel' + case node['platform'] + when 'amazon' + default['yum']['mysql57-community']['baseurl'] = 'http://repo.mysql.com/yum/mysql-5.7-community/el/6/$basearch/' + when 'redhat', 'oracle' # ~FC024 + case node['platform_version'].to_i + when 5 + # Real Redhat identifies $releasever as 5Server and 6Server + default['yum']['mysql57-community']['baseurl'] = 'http://repo.mysql.com/yum/mysql-5.7-community/el/5/$basearch/' + when 6 + default['yum']['mysql57-community']['baseurl'] = 'http://repo.mysql.com/yum/mysql-5.7-community/el/6/$basearch/' + when 7 + default['yum']['mysql57-community']['baseurl'] = 'http://repo.mysql.com/yum/mysql-5.7-community/el/7/$basearch/' + end + else # other rhel + default['yum']['mysql57-community']['baseurl'] = 'http://repo.mysql.com/yum/mysql-5.7-community/el/$releasever/$basearch/' + end +when 'fedora' + default['yum']['mysql57-community']['baseurl'] = 'http://repo.mysql.com/yum/mysql-5.7-community/fc/$releasever/$basearch/' +end diff --git a/cookbooks/yum-mysql-community/files/default/mysql_pubkey.asc b/cookbooks/yum-mysql-community/files/default/mysql_pubkey.asc new file mode 100644 index 0000000..8009b88 --- /dev/null +++ b/cookbooks/yum-mysql-community/files/default/mysql_pubkey.asc @@ -0,0 +1,33 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v1.4.5 (GNU/Linux) + +mQGiBD4+owwRBAC14GIfUfCyEDSIePvEW3SAFUdJBtoQHH/nJKZyQT7h9bPlUWC3 +RODjQReyCITRrdwyrKUGku2FmeVGwn2u2WmDMNABLnpprWPkBdCk96+OmSLN9brZ +fw2vOUgCmYv2hW0hyDHuvYlQA/BThQoADgj8AW6/0Lo7V1W9/8VuHP0gQwCgvzV3 +BqOxRznNCRCRxAuAuVztHRcEAJooQK1+iSiunZMYD1WufeXfshc57S/+yeJkegNW +hxwR9pRWVArNYJdDRT+rf2RUe3vpquKNQU/hnEIUHJRQqYHo8gTxvxXNQc7fJYLV +K2HtkrPbP72vwsEKMYhhr0eKCbtLGfls9krjJ6sBgACyP/Vb7hiPwxh6rDZ7ITnE +kYpXBACmWpP8NJTkamEnPCia2ZoOHODANwpUkP43I7jsDmgtobZX9qnrAXw+uNDI +QJEXM6FSbi0LLtZciNlYsafwAPEOMDKpMqAK6IyisNtPvaLd8lH0bPAnWqcyefep +rv0sxxqUEMcM3o7wwgfN83POkDasDbs3pjwPhxvhz6//62zQJ7Q7TXlTUUwgUGFj +a2FnZSBzaWduaW5nIGtleSAod3d3Lm15c3FsLmNvbSkgPGJ1aWxkQG15c3FsLmNv +bT6IXQQTEQIAHQULBwoDBAMVAwIDFgIBAheABQJLcC5lBQkQ8/JZAAoJEIxxjTtQ +cuH1oD4AoIcOQ4EoGsZvy06D0Ei5vcsWEy8dAJ4g46i3WEcdSWxMhcBSsPz65sh5 +lohMBBMRAgAMBQI+PqPRBYMJZgC7AAoJEElQ4SqycpHyJOEAn1mxHijft00bKXvu +cSo/pECUmppiAJ41M9MRVj5VcdH/KN/KjRtW6tHFPYhMBBMRAgAMBQI+QoIDBYMJ +YiKJAAoJELb1zU3GuiQ/lpEAoIhpp6BozKI8p6eaabzF5MlJH58pAKCu/ROofK8J +Eg2aLos+5zEYrB/LsrkCDQQ+PqMdEAgA7+GJfxbMdY4wslPnjH9rF4N2qfWsEN/l +xaZoJYc3a6M02WCnHl6ahT2/tBK2w1QI4YFteR47gCvtgb6O1JHffOo2HfLmRDRi +Rjd1DTCHqeyX7CHhcghj/dNRlW2Z0l5QFEcmV9U0Vhp3aFfWC4Ujfs3LU+hkAWzE +7zaD5cH9J7yv/6xuZVw411x0h4UqsTcWMu0iM1BzELqX1DY7LwoPEb/O9Rkbf4fm +Le11EzIaCa4PqARXQZc4dhSinMt6K3X4BrRsKTfozBu74F47D8Ilbf5vSYHbuE5p +/1oIDznkg/p8kW+3FxuWrycciqFTcNz215yyX39LXFnlLzKUb/F5GwADBQf+Lwqq +a8CGrRfsOAJxim63CHfty5mUc5rUSnTslGYEIOCR1BeQauyPZbPDsDD9MZ1ZaSaf +anFvwFG6Llx9xkU7tzq+vKLoWkm4u5xf3vn55VjnSd1aQ9eQnUcXiL4cnBGoTbOW +I39EcyzgslzBdC++MPjcQTcA7p6JUVsP6oAB3FQWg54tuUo0Ec8bsM8b3Ev42Lmu +QT5NdKHGwHsXTPtl0klk4bQk4OajHsiy1BMahpT27jWjJlMiJc+IWJ0mghkKHt92 +6s/ymfdf5HkdQ1cyvsz5tryVI3Fx78XeSYfQvuuwqp2H139pXGEkg0n6KdUOetdZ +Whe70YGNPw1yjWJT1IhMBBgRAgAMBQI+PqMdBQkJZgGAAAoJEIxxjTtQcuH17p4A +n3r1QpVC9yhnW2cSAjq+kr72GX0eAJ4295kl6NxYEuFApmr1+0uUq/SlsQ== +=Mski +-----END PGP PUBLIC KEY BLOCK----- diff --git a/cookbooks/yum-mysql-community/metadata.json b/cookbooks/yum-mysql-community/metadata.json new file mode 100644 index 0000000..61614f7 --- /dev/null +++ b/cookbooks/yum-mysql-community/metadata.json @@ -0,0 +1 @@ +{"name":"yum-mysql-community","version":"2.1.0","description":"Installs/Configures yum-mysql-community","long_description":"# yum-mysql-community Cookbook\n\n[![Build Status](https://travis-ci.org/chef-cookbooks/yum-mysql-community.svg?branch=master)](http://travis-ci.org/chef-cookbooks/yum-mysql-community) [![Cookbook Version](https://img.shields.io/cookbook/v/yum-mysql-community.svg)](https://supermarket.chef.io/cookbooks/yum-mysql-community)\n\nThe yum-mysql-community cookbook takes over management of the default repository ids shipped with mysql*-community-release. It allows attribute manipulation of `mysql-connectors-community`, `mysql56-community`, and `mysql57-community-dmr`.\n\n## Requirements\n\n### Platforms\n\n- RHEL/CentOS and derivatives\n- Fedora\n\n### Chef\n\n- Chef 12.1+\n\n### Cookbooks\n\n- compat_resource\n\n## Attributes\n\nThe following attributes are set by default\n\n```ruby\ndefault['yum']['mysql-connectors-community']['repositoryid'] = 'mysql-connectors-community'\ndefault['yum']['mysql-connectors-community']['description'] = 'MySQL Connectors Community'\ndefault['yum']['mysql-connectors-community']['baseurl'] = 'http://repo.mysql.com/yum/mysql-connectors-community/el/$releasever/$basearch/'\ndefault['yum']['mysql-connectors-community']['gpgkey'] = 'https://raw.githubusercontent.com/rs-services/equinix-public/master/cookbooks/db_mysql/files/centos/mysql_pubkey.asc'\ndefault['yum']['mysql-connectors-community']['failovermethod'] = 'priority'\ndefault['yum']['mysql-connectors-community']['gpgcheck'] = true\ndefault['yum']['mysql-connectors-community']['enabled'] = true\n```\n\n```ruby\ndefault['yum']['mysql56-community']['repositoryid'] = 'mysql56-community'\ndefault['yum']['mysql56-community']['description'] = 'MySQL 5.6 Community Server'\ndefault['yum']['mysql56-community']['baseurl'] = 'http://repo.mysql.com/yum/mysql56-community/el/$releasever/$basearch/'\ndefault['yum']['mysql56-community']['gpgkey'] = 'https://raw.githubusercontent.com/rs-services/equinix-public/master/cookbooks/db_mysql/files/centos/mysql_pubkey.asc'\ndefault['yum']['mysql56-community']['failovermethod'] = 'priority'\ndefault['yum']['mysql56-community']['gpgcheck'] = true\ndefault['yum']['mysql56-community']['enabled'] = true\n```\n\n```ruby\ndefault['yum']['mysql57-community-dmr']['repositoryid'] = 'mysql57-community-dmr'\ndefault['yum']['mysql57-community-dmr']['description'] = 'MySQL 5.7 Community Server Development Milestone Release'\ndefault['yum']['mysql57-community-dmr']['baseurl'] = 'http://repo.mysql.com/yum/mysql56-community/el/$releasever/$basearch/'\ndefault['yum']['mysql57-community-dmr']['gpgkey'] = 'https://raw.githubusercontent.com/rs-services/equinix-public/master/cookbooks/db_mysql/files/centos/mysql_pubkey.asc'\ndefault['yum']['mysql57-community-dmr']['failovermethod'] = 'priority'\ndefault['yum']['mysql57-community-dmr']['gpgcheck'] = true\ndefault['yum']['mysql57-community-dmr']['enabled'] = true\n```\n\n## Recipes\n\n- mysql55 - Sets up the mysql56-community repository on supported\n- platforms\n\n```ruby\n yum_repository 'mysql55-community' do\n mirrorlist 'https://repo.mysql.com/yum/mysql-5.5-community/el/$releasever/$basearch/'\n description ''\n enabled true\n gpgcheck true\n end\n```\n\n- mysql56 - Sets up the mysql56-community repository on supported\n- platforms\n\n```ruby\n yum_repository 'mysql56-community' do\n mirrorlist 'https://repo.mysql.com/yum/mysql-5.6-community/el/$releasever/$basearch/'\n description ''\n enabled true\n gpgcheck true\n end\n```\n\n- connectors - Sets up the mysql-connectors-community repository on supported\n- platforms\n\n## Usage Example\n\nTo disable the mysql-community-dmr repository through a Role or Environment definition\n\n```ruby\ndefault_attributes(\n :yum => {\n :mysql57-community-dmr => {\n :enabled => {\n false\n }\n }\n }\n )\n```\n\nUncommonly used repositoryids are not managed by default. This is speeds up integration testing pipelines by avoiding yum-cache builds that nobody cares about. To enable the mysql-community-dmr repository with a wrapper cookbook, place the following in a recipe:\n\n```ruby\nnode.default['yum']['mysql57-community-dmr']['enabled'] = true\nnode.default['yum']['mysql57-community-dmr']['managed'] = true\ninclude_recipe 'mysql57-community-dmr'\n```\n\n## More Examples\n\nPoint the mysql56-community repositories at an internally hosted server.\n\n```\nnode.default['yum']['mysql56-community']['enabled'] = true\nnode.default['yum']['mysql56-community']['mirrorlist'] = nil\nnode.default['yum']['mysql56-community']['baseurl'] = 'https://internal.example.com/mysql/mysql56-community/'\nnode.default['yum']['mysql56-community']['sslverify'] = false\n\ninclude_recipe 'mysql56-community'\n```\n\n## License & Authors\n\n**Author:** Cookbook Engineering Team ([cookbooks@chef.io](mailto:cookbooks@chef.io))\n\n**Copyright:** 2011-2016, Chef Software, Inc.\n\n```\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```\n","maintainer":"Chef Software, Inc.","maintainer_email":"cookbooks@chef.io","license":"Apache-2.0","platforms":{"amazon":">= 0.0.0","centos":">= 0.0.0","fedora":">= 0.0.0","oracle":">= 0.0.0","redhat":">= 0.0.0","scientific":">= 0.0.0"},"dependencies":{"compat_resource":">= 12.16.3"},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{},"source_url":"https://github.com/chef-cookbooks/yum-mysql-community","issues_url":"https://github.com/chef-cookbooks/yum-mysql-community/issues","chef_version":">= 12.1","ohai_version":{}} \ No newline at end of file diff --git a/cookbooks/yum-mysql-community/recipes/connectors.rb b/cookbooks/yum-mysql-community/recipes/connectors.rb new file mode 100644 index 0000000..58ea5b2 --- /dev/null +++ b/cookbooks/yum-mysql-community/recipes/connectors.rb @@ -0,0 +1,48 @@ +# +# Author:: Sean OMeara () +# Recipe:: yum-mysql-community::connectors +# +# Copyright:: 2014-2016, Chef Software, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +yum_repository 'mysql-connectors-community' do + description node['yum']['mysql-connectors-community']['description'] unless node['yum']['mysql-connectors-community']['description'].nil? + baseurl node['yum']['mysql-connectors-community']['baseurl'] unless node['yum']['mysql-connectors-community']['baseurl'].nil? + mirrorlist node['yum']['mysql-connectors-community']['mirrorlist'] unless node['yum']['mysql-connectors-community']['mirrorlist'].nil? + gpgcheck node['yum']['mysql-connectors-community']['gpgcheck'] unless node['yum']['mysql-connectors-community']['gpgcheck'].nil? + gpgkey node['yum']['mysql-connectors-community']['gpgkey'] unless node['yum']['mysql-connectors-community']['gpgkey'].nil? + enabled node['yum']['mysql-connectors-community']['enabled'] unless node['yum']['mysql-connectors-community']['enabled'].nil? + cost node['yum']['mysql-connectors-community']['cost'] unless node['yum']['mysql-connectors-community']['cost'].nil? + exclude node['yum']['mysql-connectors-community']['exclude'] unless node['yum']['mysql-connectors-community']['exclude'].nil? + enablegroups node['yum']['mysql-connectors-community']['enablegroups'] unless node['yum']['mysql-connectors-community']['enablegroups'].nil? + failovermethod node['yum']['mysql-connectors-community']['failovermethod'] unless node['yum']['mysql-connectors-community']['failovermethod'].nil? + http_caching node['yum']['mysql-connectors-community']['http_caching'] unless node['yum']['mysql-connectors-community']['http_caching'].nil? + include_config node['yum']['mysql-connectors-community']['include_config'] unless node['yum']['mysql-connectors-community']['include_config'].nil? + includepkgs node['yum']['mysql-connectors-community']['includepkgs'] unless node['yum']['mysql-connectors-community']['includepkgs'].nil? + keepalive node['yum']['mysql-connectors-community']['keepalive'] unless node['yum']['mysql-connectors-community']['keepalive'].nil? + max_retries node['yum']['mysql-connectors-community']['max_retries'] unless node['yum']['mysql-connectors-community']['max_retries'].nil? + metadata_expire node['yum']['mysql-connectors-community']['metadata_expire'] unless node['yum']['mysql-connectors-community']['metadata_expire'].nil? + mirror_expire node['yum']['mysql-connectors-community']['mirror_expire'] unless node['yum']['mysql-connectors-community']['mirror_expire'].nil? + priority node['yum']['mysql-connectors-community']['priority'] unless node['yum']['mysql-connectors-community']['priority'].nil? + proxy node['yum']['mysql-connectors-community']['proxy'] unless node['yum']['mysql-connectors-community']['proxy'].nil? + proxy_username node['yum']['mysql-connectors-community']['proxy_username'] unless node['yum']['mysql-connectors-community']['proxy_username'].nil? + proxy_password node['yum']['mysql-connectors-community']['proxy_password'] unless node['yum']['mysql-connectors-community']['proxy_password'].nil? + repositoryid node['yum']['mysql-connectors-community']['repositoryid'] unless node['yum']['mysql-connectors-community']['repositoryid'].nil? + sslcacert node['yum']['mysql-connectors-community']['sslcacert'] unless node['yum']['mysql-connectors-community']['sslcacert'].nil? + sslclientcert node['yum']['mysql-connectors-community']['sslclientcert'] unless node['yum']['mysql-connectors-community']['sslclientcert'].nil? + sslclientkey node['yum']['mysql-connectors-community']['sslclientkey'] unless node['yum']['mysql-connectors-community']['sslclientkey'].nil? + sslverify node['yum']['mysql-connectors-community']['sslverify'] unless node['yum']['mysql-connectors-community']['sslverify'].nil? + timeout node['yum']['mysql-connectors-community']['timeout'] unless node['yum']['mysql-connectors-community']['timeout'].nil? + action :create +end diff --git a/cookbooks/yum-mysql-community/recipes/mysql55.rb b/cookbooks/yum-mysql-community/recipes/mysql55.rb new file mode 100644 index 0000000..512aa63 --- /dev/null +++ b/cookbooks/yum-mysql-community/recipes/mysql55.rb @@ -0,0 +1,48 @@ +# +# Author:: Sean OMeara () +# Recipe:: yum-mysql-community::mysql55 +# +# Copyright:: 2014-2016, Chef Software, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +yum_repository 'mysql55-community' do + description node['yum']['mysql55-community']['description'] unless node['yum']['mysql55-community']['description'].nil? + baseurl node['yum']['mysql55-community']['baseurl'] unless node['yum']['mysql55-community']['baseurl'].nil? + mirrorlist node['yum']['mysql55-community']['mirrorlist'] unless node['yum']['mysql55-community']['mirrorlist'].nil? + gpgcheck node['yum']['mysql55-community']['gpgcheck'] unless node['yum']['mysql55-community']['gpgcheck'].nil? + gpgkey node['yum']['mysql55-community']['gpgkey'] unless node['yum']['mysql55-community']['gpgkey'].nil? + enabled node['yum']['mysql55-community']['enabled'] unless node['yum']['mysql55-community']['enabled'].nil? + cost node['yum']['mysql55-community']['cost'] unless node['yum']['mysql55-community']['cost'].nil? + exclude node['yum']['mysql55-community']['exclude'] unless node['yum']['mysql55-community']['exclude'].nil? + enablegroups node['yum']['mysql55-community']['enablegroups'] unless node['yum']['mysql55-community']['enablegroups'].nil? + failovermethod node['yum']['mysql55-community']['failovermethod'] unless node['yum']['mysql55-community']['failovermethod'].nil? + http_caching node['yum']['mysql55-community']['http_caching'] unless node['yum']['mysql55-community']['http_caching'].nil? + include_config node['yum']['mysql55-community']['include_config'] unless node['yum']['mysql55-community']['include_config'].nil? + includepkgs node['yum']['mysql55-community']['includepkgs'] unless node['yum']['mysql55-community']['includepkgs'].nil? + keepalive node['yum']['mysql55-community']['keepalive'] unless node['yum']['mysql55-community']['keepalive'].nil? + max_retries node['yum']['mysql55-community']['max_retries'] unless node['yum']['mysql55-community']['max_retries'].nil? + metadata_expire node['yum']['mysql55-community']['metadata_expire'] unless node['yum']['mysql55-community']['metadata_expire'].nil? + mirror_expire node['yum']['mysql55-community']['mirror_expire'] unless node['yum']['mysql55-community']['mirror_expire'].nil? + priority node['yum']['mysql55-community']['priority'] unless node['yum']['mysql55-community']['priority'].nil? + proxy node['yum']['mysql55-community']['proxy'] unless node['yum']['mysql55-community']['proxy'].nil? + proxy_username node['yum']['mysql55-community']['proxy_username'] unless node['yum']['mysql55-community']['proxy_username'].nil? + proxy_password node['yum']['mysql55-community']['proxy_password'] unless node['yum']['mysql55-community']['proxy_password'].nil? + repositoryid node['yum']['mysql55-community']['repositoryid'] unless node['yum']['mysql55-community']['repositoryid'].nil? + sslcacert node['yum']['mysql55-community']['sslcacert'] unless node['yum']['mysql55-community']['sslcacert'].nil? + sslclientcert node['yum']['mysql55-community']['sslclientcert'] unless node['yum']['mysql55-community']['sslclientcert'].nil? + sslclientkey node['yum']['mysql55-community']['sslclientkey'] unless node['yum']['mysql55-community']['sslclientkey'].nil? + sslverify node['yum']['mysql55-community']['sslverify'] unless node['yum']['mysql55-community']['sslverify'].nil? + timeout node['yum']['mysql55-community']['timeout'] unless node['yum']['mysql55-community']['timeout'].nil? + action :create +end diff --git a/cookbooks/yum-mysql-community/recipes/mysql56.rb b/cookbooks/yum-mysql-community/recipes/mysql56.rb new file mode 100644 index 0000000..9ba3f10 --- /dev/null +++ b/cookbooks/yum-mysql-community/recipes/mysql56.rb @@ -0,0 +1,48 @@ +# +# Author:: Sean OMeara () +# Recipe:: yum-mysql-community::mysql56-community +# +# Copyright:: 2014-2016, Chef Software, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +yum_repository 'mysql56-community' do + description node['yum']['mysql56-community']['description'] unless node['yum']['mysql56-community']['description'].nil? + baseurl node['yum']['mysql56-community']['baseurl'] unless node['yum']['mysql56-community']['baseurl'].nil? + mirrorlist node['yum']['mysql56-community']['mirrorlist'] unless node['yum']['mysql56-community']['mirrorlist'].nil? + gpgcheck node['yum']['mysql56-community']['gpgcheck'] unless node['yum']['mysql56-community']['gpgcheck'].nil? + gpgkey node['yum']['mysql56-community']['gpgkey'] unless node['yum']['mysql56-community']['gpgkey'].nil? + enabled node['yum']['mysql56-community']['enabled'] unless node['yum']['mysql56-community']['enabled'].nil? + cost node['yum']['mysql56-community']['cost'] unless node['yum']['mysql56-community']['cost'].nil? + exclude node['yum']['mysql56-community']['exclude'] unless node['yum']['mysql56-community']['exclude'].nil? + enablegroups node['yum']['mysql56-community']['enablegroups'] unless node['yum']['mysql56-community']['enablegroups'].nil? + failovermethod node['yum']['mysql56-community']['failovermethod'] unless node['yum']['mysql56-community']['failovermethod'].nil? + http_caching node['yum']['mysql56-community']['http_caching'] unless node['yum']['mysql56-community']['http_caching'].nil? + include_config node['yum']['mysql56-community']['include_config'] unless node['yum']['mysql56-community']['include_config'].nil? + includepkgs node['yum']['mysql56-community']['includepkgs'] unless node['yum']['mysql56-community']['includepkgs'].nil? + keepalive node['yum']['mysql56-community']['keepalive'] unless node['yum']['mysql56-community']['keepalive'].nil? + max_retries node['yum']['mysql56-community']['max_retries'] unless node['yum']['mysql56-community']['max_retries'].nil? + metadata_expire node['yum']['mysql56-community']['metadata_expire'] unless node['yum']['mysql56-community']['metadata_expire'].nil? + mirror_expire node['yum']['mysql56-community']['mirror_expire'] unless node['yum']['mysql56-community']['mirror_expire'].nil? + priority node['yum']['mysql56-community']['priority'] unless node['yum']['mysql56-community']['priority'].nil? + proxy node['yum']['mysql56-community']['proxy'] unless node['yum']['mysql56-community']['proxy'].nil? + proxy_username node['yum']['mysql56-community']['proxy_username'] unless node['yum']['mysql56-community']['proxy_username'].nil? + proxy_password node['yum']['mysql56-community']['proxy_password'] unless node['yum']['mysql56-community']['proxy_password'].nil? + repositoryid node['yum']['mysql56-community']['repositoryid'] unless node['yum']['mysql56-community']['repositoryid'].nil? + sslcacert node['yum']['mysql56-community']['sslcacert'] unless node['yum']['mysql56-community']['sslcacert'].nil? + sslclientcert node['yum']['mysql56-community']['sslclientcert'] unless node['yum']['mysql56-community']['sslclientcert'].nil? + sslclientkey node['yum']['mysql56-community']['sslclientkey'] unless node['yum']['mysql56-community']['sslclientkey'].nil? + sslverify node['yum']['mysql56-community']['sslverify'] unless node['yum']['mysql56-community']['sslverify'].nil? + timeout node['yum']['mysql56-community']['timeout'] unless node['yum']['mysql56-community']['timeout'].nil? + action :create +end diff --git a/cookbooks/yum-mysql-community/recipes/mysql57.rb b/cookbooks/yum-mysql-community/recipes/mysql57.rb new file mode 100644 index 0000000..4236176 --- /dev/null +++ b/cookbooks/yum-mysql-community/recipes/mysql57.rb @@ -0,0 +1,48 @@ +# +# Author:: Sean OMeara () +# Recipe:: yum-mysql-community::mysql57-community +# +# Copyright:: 2014-2016, Chef Software, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +yum_repository 'mysql57-community' do + description node['yum']['mysql57-community']['description'] unless node['yum']['mysql57-community']['description'].nil? + baseurl node['yum']['mysql57-community']['baseurl'] unless node['yum']['mysql57-community']['baseurl'].nil? + mirrorlist node['yum']['mysql57-community']['mirrorlist'] unless node['yum']['mysql57-community']['mirrorlist'].nil? + gpgcheck node['yum']['mysql57-community']['gpgcheck'] unless node['yum']['mysql57-community']['gpgcheck'].nil? + gpgkey node['yum']['mysql57-community']['gpgkey'] unless node['yum']['mysql57-community']['gpgkey'].nil? + enabled node['yum']['mysql57-community']['enabled'] unless node['yum']['mysql57-community']['enabled'].nil? + cost node['yum']['mysql57-community']['cost'] unless node['yum']['mysql57-community']['cost'].nil? + exclude node['yum']['mysql57-community']['exclude'] unless node['yum']['mysql57-community']['exclude'].nil? + enablegroups node['yum']['mysql57-community']['enablegroups'] unless node['yum']['mysql57-community']['enablegroups'].nil? + failovermethod node['yum']['mysql57-community']['failovermethod'] unless node['yum']['mysql57-community']['failovermethod'].nil? + http_caching node['yum']['mysql57-community']['http_caching'] unless node['yum']['mysql57-community']['http_caching'].nil? + include_config node['yum']['mysql57-community']['include_config'] unless node['yum']['mysql57-community']['include_config'].nil? + includepkgs node['yum']['mysql57-community']['includepkgs'] unless node['yum']['mysql57-community']['includepkgs'].nil? + keepalive node['yum']['mysql57-community']['keepalive'] unless node['yum']['mysql57-community']['keepalive'].nil? + max_retries node['yum']['mysql57-community']['max_retries'] unless node['yum']['mysql57-community']['max_retries'].nil? + metadata_expire node['yum']['mysql57-community']['metadata_expire'] unless node['yum']['mysql57-community']['metadata_expire'].nil? + mirror_expire node['yum']['mysql57-community']['mirror_expire'] unless node['yum']['mysql57-community']['mirror_expire'].nil? + priority node['yum']['mysql57-community']['priority'] unless node['yum']['mysql57-community']['priority'].nil? + proxy node['yum']['mysql57-community']['proxy'] unless node['yum']['mysql57-community']['proxy'].nil? + proxy_username node['yum']['mysql57-community']['proxy_username'] unless node['yum']['mysql57-community']['proxy_username'].nil? + proxy_password node['yum']['mysql57-community']['proxy_password'] unless node['yum']['mysql57-community']['proxy_password'].nil? + repositoryid node['yum']['mysql57-community']['repositoryid'] unless node['yum']['mysql57-community']['repositoryid'].nil? + sslcacert node['yum']['mysql57-community']['sslcacert'] unless node['yum']['mysql57-community']['sslcacert'].nil? + sslclientcert node['yum']['mysql57-community']['sslclientcert'] unless node['yum']['mysql57-community']['sslclientcert'].nil? + sslclientkey node['yum']['mysql57-community']['sslclientkey'] unless node['yum']['mysql57-community']['sslclientkey'].nil? + sslverify node['yum']['mysql57-community']['sslverify'] unless node['yum']['mysql57-community']['sslverify'].nil? + timeout node['yum']['mysql57-community']['timeout'] unless node['yum']['mysql57-community']['timeout'].nil? + action :create +end