Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added LogCustomFields to xWebSite (Fixes #267) #342

Merged
merged 11 commits into from
May 4, 2018
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