Skip to content

Commit

Permalink
Added LogCustomFields to xWebSite (dsccommunity#342)
Browse files Browse the repository at this point in the history
- Updated xWebSite to include ability to manage custom logging fields (issue dsccommunity#267).
  • Loading branch information
regedit32 authored and johlju committed May 4, 2018
1 parent 6dc1bc8 commit f18f516
Show file tree
Hide file tree
Showing 8 changed files with 496 additions and 18 deletions.
3 changes: 3 additions & 0 deletions .MetaTestOptIn.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[
"null"
]
171 changes: 164 additions & 7 deletions DSCResources/MSFT_xWebsite/MSFT_xWebsite.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ data LocalizedData
VerboseSetTargetUpdateLogTruncateSize = TruncateSize does not match and will be updated on Website "{0}".
VerboseSetTargetUpdateLoglocalTimeRollover = LoglocalTimeRollover does not match and will be updated on Website "{0}".
VerboseSetTargetUpdateLogFormat = LogFormat is not in the desired state and will be updated on Website "{0}"
VerboseSetTargetUpdateLogCustomFields = LogCustomFields is not in the desired state and will be updated on Website "{0}"
VerboseTestTargetFalseEnsure = The Ensure state for website "{0}" does not match the desired state.
VerboseTestTargetFalsePhysicalPath = Physical Path of website "{0}" does not match the desired state.
VerboseTestTargetFalseState = The state of website "{0}" does not match the desired state.
Expand All @@ -69,6 +70,7 @@ data LocalizedData
VerboseTestTargetFalseLogTruncateSize = LogTruncateSize does not match desired state on Website "{0}".
VerboseTestTargetFalseLoglocalTimeRollover = LoglocalTimeRollover does not match desired state on Website "{0}".
VerboseTestTargetFalseLogFormat = LogFormat does not match desired state on Website "{0}".
VerboseTestTargetFalseLogCustomFields = LogCustomFields does not match desired state on Website "{0}".
VerboseConvertToWebBindingIgnoreBindingInformation = BindingInformation is ignored for bindings of type "{0}" in case at least one of the following properties is specified: IPAddress, Port, HostName.
VerboseConvertToWebBindingDefaultPort = Port is not specified. The default "{0}" port "{1}" will be used.
VerboseConvertToWebBindingDefaultCertificateStoreName = CertificateStoreName is not specified. The default value "{0}" will be used.
Expand Down Expand Up @@ -130,6 +132,8 @@ function Get-TargetResource
$webConfiguration = $websiteAutoStartProviders | `
Where-Object -Property Name -eq -Value $ServiceAutoStartProvider | `
Select-Object Name,Type

$cimLogCustomFields = ConvertTo-CimLogCustomFields -InputObject $website.logFile.customFields.Collection
}
# Multiple websites with the same name exist. This is not supported and is an error
else
Expand Down Expand Up @@ -161,6 +165,7 @@ function Get-TargetResource
LogtruncateSize = $website.logfile.truncateSize
LoglocalTimeRollover = $website.logfile.localTimeRollover
LogFormat = $website.logfile.logFormat
LogCustomFields = $cimLogCustomFields
}
}

Expand Down Expand Up @@ -244,7 +249,10 @@ function Set-TargetResource

[ValidateSet('IIS','W3C','NCSA')]
[String]
$LogFormat
$LogFormat,

[Microsoft.Management.Infrastructure.CimInstance[]]
$LogCustomFields
)

Assert-Module
Expand Down Expand Up @@ -491,7 +499,7 @@ function Set-TargetResource
-Name LogFile.period -Value 'MaxSize'
}

# Update LoglocalTimeRollover if neeed
# Update LoglocalTimeRollover if needed
if ($PSBoundParameters.ContainsKey('LoglocalTimeRollover') -and `
($LoglocalTimeRollover -ne `
([System.Convert]::ToBoolean($website.logfile.LocalTimeRollover))))
Expand All @@ -501,7 +509,6 @@ function Set-TargetResource
Set-ItemProperty -Path "IIS:\Sites\$Name" `
-Name LogFile.localTimeRollover -Value $LoglocalTimeRollover
}

}
# Create website if it does not exist
else
Expand Down Expand Up @@ -740,7 +747,7 @@ function Set-TargetResource
-Name LogFile.period -Value 'MaxSize'
}

# Update LoglocalTimeRollover if neeed
# Update LoglocalTimeRollover if needed
if ($PSBoundParameters.ContainsKey('LoglocalTimeRollover') -and `
($LoglocalTimeRollover -ne `
([System.Convert]::ToBoolean($website.logfile.LocalTimeRollover))))
Expand All @@ -751,6 +758,15 @@ function Set-TargetResource
-Name LogFile.localTimeRollover -Value $LoglocalTimeRollover
}
}

# Update LogCustomFields if needed
if ($PSBoundParameters.ContainsKey('LogCustomFields') -and `
(-not (Test-LogCustomField -Site $Name -LogCustomField $LogCustomFields)))
{
Write-Verbose -Message ($LocalizedData.VerboseSetTargetUpdateLogCustomFields `
-f $Name)
Set-LogCustomField -Site $Name -LogCustomField $LogCustomFields
}
}
# Remove website
else
Expand Down Expand Up @@ -850,7 +866,10 @@ function Test-TargetResource

[ValidateSet('IIS','W3C','NCSA')]
[String]
$LogFormat
$LogFormat,

[Microsoft.Management.Infrastructure.CimInstance[]]
$LogCustomFields
)

Assert-Module
Expand Down Expand Up @@ -1058,6 +1077,15 @@ function Test-TargetResource
-f $Name)
return $false
}

# Check LogCustomFields if needed
if ($PSBoundParameters.ContainsKey('LogCustomFields') -and `
(-not (Test-LogCustomField -Site $Name -LogCustomField $LogCustomFields)))
{
Write-Verbose -Message ($LocalizedData.VerboseTestTargetUpdateLogCustomFields `
-f $Name)
return $false
}
}

if ($inDesiredState -eq $true)
Expand Down Expand Up @@ -1587,6 +1615,44 @@ function ConvertTo-WebBinding
}
}

<#
.SYNOPSIS
Converts IIS custom log field collection to instances of the MSFT_xLogCustomFieldInformation CIM class.
#>
function ConvertTo-CimLogCustomFields
{
[CmdletBinding()]
[OutputType([Microsoft.Management.Infrastructure.CimInstance[]])]
param
(
[Parameter(Mandatory = $true)]
[AllowEmptyCollection()]
[AllowNull()]
[Object[]]
$InputObject
)

$cimClassName = 'MSFT_xLogCustomFieldInformation'
$cimNamespace = 'root/microsoft/Windows/DesiredStateConfiguration'
$cimCollection = New-Object -TypeName 'System.Collections.ObjectModel.Collection`1[Microsoft.Management.Infrastructure.CimInstance]'

foreach ($customField in $InputObject)
{
$cimProperties = @{
LogFieldName = $customField.LogFieldName
SourceName = $customField.SourceName
SourceType = $customField.SourceType
}

$cimCollection += (New-CimInstance -ClassName $cimClassName `
-Namespace $cimNamespace `
-Property $cimProperties `
-ClientOnly)
}

return $cimCollection
}

<#
.SYNOPSYS
Formats the input IP address string for use in the bindingInformation attribute.
Expand Down Expand Up @@ -1747,6 +1813,48 @@ function Set-AuthenticationInfo
}
}

<#
.SYNOPSIS
Helper function used to set the LogCustomField for a website.
.PARAMETER Site
Specifies the name of the Website.
.PARAMETER LogCustomField
A CimInstance collection of what the LogCustomField should be.
#>
function Set-LogCustomField
{
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true)]
[String]
$Site,

[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[Microsoft.Management.Infrastructure.CimInstance[]]
$LogCustomField
)

$setCustomFields = @()
foreach ($customField in $LogCustomField)
{
$setCustomFields += @{
logFieldName = $customField.LogFieldName
sourceName = $customField.SourceName
sourceType = $customField.SourceType
}
}

# The second Set-WebConfigurationProperty is to handle an edge case where logfile.customFields is not updated correctly. May be caused by a possible bug in the IIS provider
for ($i = 1; $i -le 2; $i++)
{
Set-WebConfigurationProperty -PSPath 'MACHINE/WEBROOT/APPHOST' -Filter "system.applicationHost/sites/site[@name='$Site']/logFile/customFields" -Name "." -Value $setCustomFields
}
}

<#
.SYNOPSIS
Helper function used to test the authenticationProperties state for an Application.
Expand Down Expand Up @@ -2002,6 +2110,57 @@ function Test-WebsiteBinding
return $inDesiredState
}

<#
.SYNOPSIS
Helper function used to test the LogCustomField state for a website.
.PARAMETER Site
Specifies the name of the Website.
.PARAMETER LogCustomField
A CimInstance collection of what state the LogCustomField should be.
#>
function Test-LogCustomField
{
[CmdletBinding()]
[OutputType([Boolean])]
param
(
[Parameter(Mandatory = $true)]
[String]
$Site,

[Parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[Microsoft.Management.Infrastructure.CimInstance[]]
$LogCustomField
)

$inDesiredSate = $true

foreach ($customField in $LogCustomField)
{
$filterString = "/system.applicationHost/sites/site[@name='{0}']/logFile/customFields/add[@logFieldName='{1}']" -f $Site, $customField.LogFieldName
$presentCustomField = Get-WebConfigurationProperty -Filter $filterString -Name "."

if ($presentCustomField)
{
$sourceNameMatch = $customField.SourceName -eq $presentCustomField.SourceName
$sourceTypeMatch = $customField.SourceType -eq $presentCustomField.sourceType
if (-not ($sourceNameMatch -and $sourceTypeMatch))
{
$inDesiredSate = $false
}
}
else
{
$inDesiredSate = $false
}
}

return $inDesiredSate
}

<#
.SYNOPSIS
Helper function used to update default pages of website.
Expand Down Expand Up @@ -2143,5 +2302,3 @@ function Update-WebsiteBinding
#endregion

Export-ModuleMember -Function *-TargetResource


9 changes: 9 additions & 0 deletions DSCResources/MSFT_xWebsite/MSFT_xWebsite.schema.mof
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@ class MSFT_xWebAuthenticationInformation
[Write] Boolean Windows;
};

[ClassVersion("1.0.0")]
class MSFT_xLogCustomFieldInformation
{
[Write] String LogFieldName;
[Write] String SourceName;
[Write, ValueMap{"RequestHeader","ResponseHeader","ServerVariable"},Values{"RequestHeader","ResponseHeader","ServerVariable"}] String SourceType;
};

[ClassVersion("2.0.0"), FriendlyName("xWebsite")]
class MSFT_xWebsite : OMI_BaseResource
{
Expand All @@ -43,4 +51,5 @@ class MSFT_xWebsite : OMI_BaseResource
[Write, Description ("How large the file should be before it is truncated")] String LogTruncateSize;
[Write, Description ("Use the localtime for file naming and rollover")] Boolean LoglocalTimeRollover;
[Write, Description ("Format of the Logfiles. Only W3C supports LogFlags"), ValueMap{"IIS","W3C","NCSA"}, Values{"IIS","W3C","NCSA"}] String LogFormat;
[Write, EmbeddedInstance("MSFT_xLogCustomFieldInformation"), Description("Custom logging field information in the form of an array of embedded instances of MSFT_xLogCustomFieldInformation CIM class")] String LogCustomFields[];
};
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,10 @@ Please check out common DSC Resources [contributing guidelines](https://github.c
* **LogTruncateSize**: How large the file should be before it is truncated. If this is set then LogPeriod will be ignored if passed in and set to MaxSize. The value must be a valid integer between `1048576 (1MB)` and `4294967295 (4GB)`.
* **LoglocalTimeRollover**: Use the localtime for file naming and rollover. The acceptable values for this property are: `$true`, `$false`
* **LogFormat**: Format of the Logfiles. **Note**Only W3C supports LogFlags. The acceptable values for this property are: `IIS`,`W3C`,`NCSA`
* **LogCustomFields**: Custom logging field information the form of an array of embedded instances of the **MSFT_xLogCustomFieldInformation** CIM class that implements the following properties:
* **LogFieldName**: Field name to identify the custom field within the log file. Please note that the field name cannot contain spaces.
* **SourceName**: You can select `RequestHeader`, `ResponseHeader`, or `ServerVariable` (note that enhanced logging cannot log a server variable with a name that contains lower-case characters - to include a server variable in the event log just make sure that its name consists of all upper-case characters).
* **SourceType**: Name of the HTTP header or server variable (depending on the Source Type you selected) that contains a value that you want to log.

### xWebApplication

Expand Down Expand Up @@ -257,6 +261,7 @@ Please check out common DSC Resources [contributing guidelines](https://github.c
## Versions

### Unreleased
* Updated **xWebSite** to include ability to manage custom logging fields

### 1.20.0.0

Expand Down
18 changes: 16 additions & 2 deletions Tests/Integration/MSFT_xWebsite.Integration.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,14 @@ try
#Test DefaultPage is correct
$defultPages[0] | Should Match $dscConfig.AllNodes.DefaultPage

}
#Test LogCustomFields is correct
$result.logFile.customFields.Collection[0].LogFieldName | Should Be $dscConfig.AllNodes.LogFieldName1
$result.logFile.customFields.Collection[0].SourceName | Should Be $dscConfig.AllNodes.SourceName1
$result.logFile.customFields.Collection[0].SourceType | Should Be $dscConfig.AllNodes.SourceType1
$result.logFile.customFields.Collection[1].LogFieldName | Should Be $dscConfig.AllNodes.LogFieldName2
$result.logFile.customFields.Collection[1].SourceName | Should Be $dscConfig.AllNodes.SourceName2
$result.logFile.customFields.Collection[1].SourceType | Should Be $dscConfig.AllNodes.SourceType2
}

}

Expand Down Expand Up @@ -195,7 +202,14 @@ try
#Test DefaultPage is correct
$defultPages[0] | Should Match $dscConfig.AllNodes.DefaultPage

}
#Test LogCustomFields is correct
$result.logFile.customFields.Collection[0].LogFieldName | Should Be $dscConfig.AllNodes.LogFieldName1
$result.logFile.customFields.Collection[0].SourceName | Should Be $dscConfig.AllNodes.SourceName1
$result.logFile.customFields.Collection[0].SourceType | Should Be $dscConfig.AllNodes.SourceType1
$result.logFile.customFields.Collection[1].LogFieldName | Should Be $dscConfig.AllNodes.LogFieldName2
$result.logFile.customFields.Collection[1].SourceName | Should Be $dscConfig.AllNodes.SourceName2
$result.logFile.customFields.Collection[1].SourceType | Should Be $dscConfig.AllNodes.SourceType2
}

}

Expand Down
Loading

0 comments on commit f18f516

Please sign in to comment.