Skip to content

Commit

Permalink
Adds support for iis_app InSpec testing
Browse files Browse the repository at this point in the history
Signed-off-by: Justin Schuhmann <jmschu02@gmail.com>
  • Loading branch information
EasyAsABC123 committed Jun 7, 2017
1 parent 4f34e3e commit da9d24e
Show file tree
Hide file tree
Showing 5 changed files with 254 additions and 2 deletions.
126 changes: 126 additions & 0 deletions docs/resources/iis_app.md.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
---
title: About the iis_app Resource
---

# iis_app

Use the `iis_app` InSpec audit resource to test the state of IIS on Windows Server 2012 (and later).

## Syntax

An `iis_app` resource block declares details about the named site:

describe iis_app('application_path', 'site_name') do
it { should exist }
it { should have_application_pool('application_pool') }
it { should have_protocols('protocol') }
it { should have_site_name('site') }
it { should have_physical_path('physical_path') }
it { should have_path('application_path') }
end

where

* `'application_path'` is the path to the application, such as `'/myapp'`
* `'site_name'` is the name of the site, such as `'Default Web Site'`
* `('application_pool')` is the name of the application pool in which the site's root application is run, such as `'DefaultAppPool'`
* `('protocols')` is a binding for the site, such as `'http'`. A site may have multiple bindings; therefore, use a `have_protocol` matcher for each site protocol to be tested
* `('physical_path') is the physical path to the application, such as `'C:\\inetpub\\wwwroot\\myapp'`

For example:

describe iis_app('/myapp', 'Default Web Site') do
it { should exist }
it { should have_application_pool('MyAppPool') }
it { should have_protocols('http') }
it { should have_site_name('Default Web Site') }
it { should have_physical_path('C:\\inetpub\\wwwroot\\myapp') }
it { should have_path('\\My Application') }
end

## Matchers

This InSpec audit resource has the following matchers:

### cmp

<%= partial "/shared/matcher_cmp" %>

### eq

<%= partial "/shared/matcher_eq" %>

### exist

The `exist` matcher tests if the site exists:

it { should exist }

### have\_application\_pool

The `have_application_pool` matcher tests if the named application pool exists for the web application:

it { should have_application_pool('DefaultAppPool') }

### have_protocol

The `have_protocol` matcher tests if the specified protocol exists for the web application:

it { should have_protocol('http') }

or:

it { should have_protocol('https') }

A web application may have multiple bindings; use a `have_protocol` matcher for each unique web application binding to be tested.

##### Protocol Attributes

The `have_protocol` matcher can also test attributes that are defined for a web application enabledProtocols.

it { should have_protocol('http') }

For example, testing a site that doesn't have https enabled:

it { should_not have_protocol('https') }
it { should have_protocol('http') }

Testing a web application with https enabled and http enabled:

it { should have_protocol('https') }
it { should have_protocol('http') }

### have_physical_path

The `have_physical_path` matcher tests if the named path is defined for the web application:

it { should have_physical_path('C:\\inetpub\\wwwroot') }

### include

<%= partial "/shared/matcher_include" %>

### match

<%= partial "/shared/matcher_match" %>

## Examples

The following examples show how to use this InSpec audit resource.

### Test a default IIS web application

describe iis_app('Default Web Site') do
it { should exist }
it { should be_running }
it { should have_app_pool('DefaultAppPool') }
it { should have_binding('http *:80:') }
it { should have_path('%SystemDrive%\\inetpub\\wwwroot') }
end

### Test if IIS service is running

describe service('W3SVC') do
it { should be_installed }
it { should be_running }
end
1 change: 1 addition & 0 deletions lib/inspec/resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ def self.validate_resource_dsl_version!(version)
require 'resources/grub_conf'
require 'resources/host'
require 'resources/http'
require 'resources/iis_app'
require 'resources/iis_site'
require 'resources/inetd_conf'
require 'resources/interface'
Expand Down
125 changes: 125 additions & 0 deletions lib/resources/iis_app.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
# encoding: utf-8
# frozen_string_literal: true
# check for web applications in IIS
# Usage:
# describe iis_app('/myapp', 'Website') do
# it { should exist }
# it { should have_application_pool('MyAppPool') }
# it { should have_protocols('http') }
# it { should have_site_name('Default Web Site') }
# it { should have_physical_path('C:\\inetpub\\wwwroot\\myapp') }
# it { should have_path('\\My Application') }
# end
#
# Note: this is only supported in windows 2012 and later
module Inspec::Resources
class IisApp < Inspec.resource(1)
name 'iis_app'
desc 'Tests IIS application configuration on windows. Supported in server 2012+ only'
example "
describe iis_app('/myapp', 'Default Web Site') do
it { should exist }
it { should have_application_pool('MyAppPool') }
it { should have_protocols('http') }
it { should have_site_name('Default Web Site') }
it { should have_physical_path('C:\\inetpub\\wwwroot\\myapp') }
it { should have_path('\\My Application') }
end
"

def initialize(path, site_name)
@path = path
@site_name = site_name
@cache = nil

@app_provider = AppProvider.new(inspec)

# verify that this resource is only supported on Windows
return skip_resource 'The `iis_app` resource is not supported on your OS.' unless inspec.os.windows?
end

def application_pool
iis_app[:application_pool]
end

def protocols
iis_app[:protocols]
end

def site_name
iis_app[:site_name]
end

def path
iis_app[:path]
end

def physical_path
iis_app[:physical_path]
end

def exists?
!iis_app[:path].empty?
end

def has_site_name?(site_name)
iis_app[:site_name] == site_name
end

def has_application_pool?(application_pool)
iis_app[:application_pool] == application_pool
end

def has_path?(path)
iis_app[:path] == path
end

def has_physical_path?(physical_path)
iis_app[:physical_path] == physical_path
end

def has_protocol?(protocol)
(iis_app[:protocols].include? protocol)
end

def to_s
"iis_app '#{@site_name}#{@path}'"
end

def iis_app
return @cache unless @cache.nil?
@cache = @app_provider.iis_app(@path, @site_name) unless @app_provider.nil?
end
end

class AppProvider
attr_reader :inspec

def initialize(inspec)
@inspec = inspec
end

# want to populate everything using one powershell command here and spit it out as json
def iis_app(path, site_name)
command = "Import-Module WebAdministration; Get-WebApplication -Name '#{path}' -Site '#{site_name}' | Select-Object * | ConvertTo-Json"
cmd = @inspec.command(command)

begin
app = JSON.parse(cmd.stdout)
rescue JSON::ParserError => _e
return {}
end

# map our values to a hash table
info = {
site_name: site_name,
path: path,
application_pool: app['applicationPool'],
physical_path: app['PhysicalPath'],
protocols: app['enabledProtocols'],
}

info
end
end
end
2 changes: 1 addition & 1 deletion test/cookbooks/os_prepare/recipes/default.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
include_recipe('os_prepare::service')
include_recipe('os_prepare::package')
include_recipe('os_prepare::registry_key')
include_recipe('os_prepare::iis_site')
include_recipe('os_prepare::iis')
include_recipe('os_prepare::iptables') unless node['osprepare']['docker']
include_recipe('os_prepare::x509')
include_recipe('os_prepare::dh_params')
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# set up test site for iis_site resource
# set up test site for iis resource

return unless node['platform_family'] == 'windows'

Expand Down

0 comments on commit da9d24e

Please sign in to comment.