Merge pull request #119 from Icinga/feature/mssql_connector

Feature: Adds MSSQL connector
This commit is contained in:
Lord Hepipud 2020-08-28 09:31:19 +02:00 committed by GitHub
commit 2863f0e0e7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 234 additions and 1 deletions

View file

@ -5,7 +5,7 @@ function Exit-IcingaThrowException()
[string]$StringPattern, [string]$StringPattern,
[string]$CustomMessage, [string]$CustomMessage,
[string]$ExceptionThrown, [string]$ExceptionThrown,
[ValidateSet('Permission', 'Input', 'Configuration', 'Unhandled', 'Custom')] [ValidateSet('Permission', 'Input', 'Configuration', 'Connection', 'Unhandled', 'Custom')]
[string]$ExceptionType = 'Unhandled', [string]$ExceptionType = 'Unhandled',
[switch]$Force [switch]$Force
); );
@ -36,6 +36,10 @@ function Exit-IcingaThrowException()
$ExceptionTypeString = 'Invalid Configuration'; $ExceptionTypeString = 'Invalid Configuration';
$ExceptionMessageLib = $IcingaExceptions.Configuration; $ExceptionMessageLib = $IcingaExceptions.Configuration;
}; };
'Connection' {
$ExceptionTypeString = 'Connection error';
$ExceptionMessageLib = $IcingaExceptions.Connection;
};
'Unhandled' { 'Unhandled' {
$ExceptionTypeString = 'Unhandled'; $ExceptionTypeString = 'Unhandled';
}; };

View file

@ -19,6 +19,8 @@
ConversionUnitMissing = 'Unable to parse input value. You have to add an unit to your input value. Example: "10GB". Allowed units are: "B, KB, MB, GB, TB, PB, KiB, MiB, GiB, TiB, PiB".'; ConversionUnitMissing = 'Unable to parse input value. You have to add an unit to your input value. Example: "10GB". Allowed units are: "B, KB, MB, GB, TB, PB, KiB, MiB, GiB, TiB, PiB".';
CimClassNameUnknown = 'The provided class name you try to fetch with Get-CimInstance is not known on this system.'; CimClassNameUnknown = 'The provided class name you try to fetch with Get-CimInstance is not known on this system.';
WmiObjectClassUnknown = 'The provided class name you try to fetch with Get-WmiObject is not known on this system.'; WmiObjectClassUnknown = 'The provided class name you try to fetch with Get-WmiObject is not known on this system.';
MSSQLCredentialHandling = 'The connection to MSSQL was not possbible because your login credential was not correct.';
MSSQLCommandMissing = 'Failed to build a SQL query'
}; };
[hashtable]$Configuration = @{ [hashtable]$Configuration = @{
@ -30,6 +32,10 @@
PerfCounterCategoryMissing = 'The specified Performance Counter category was not found on this system. This could either be a configuration error on your local Windows machine or a wrong usage of the plugin. Please check on different Windows machines if this issue persis. In case it only occurs on certain machines it is likely that the counter is simply not present and the plugin can not be processed.'; PerfCounterCategoryMissing = 'The specified Performance Counter category was not found on this system. This could either be a configuration error on your local Windows machine or a wrong usage of the plugin. Please check on different Windows machines if this issue persis. In case it only occurs on certain machines it is likely that the counter is simply not present and the plugin can not be processed.';
} }
[hashtable]$Connection = @{
MSSQLConnectionError = 'Could not open a connection to SQL Server. This failure may be caused by the fact that under the default settings SQL Server does not allow remote connections or the host is unreachable.';
}
<# <#
# Once we defined a new enum hashtable above, simply add it to this list # Once we defined a new enum hashtable above, simply add it to this list
# to make it available within the entire module. # to make it available within the entire module.
@ -41,6 +47,7 @@
Permission = $Permission; Permission = $Permission;
Inputs = $Inputs; Inputs = $Inputs;
Configuration = $Configuration; Configuration = $Configuration;
Connection = $Connection;
} }
Export-ModuleMember -Variable @( 'IcingaExceptions' ); Export-ModuleMember -Variable @( 'IcingaExceptions' );

View file

@ -0,0 +1,33 @@
<#
.SYNOPSIS
Closes a open connection to a MSSQL server
.DESCRIPTION
This Cmdlet will close an open connection to a MSSQL server.
.FUNCTIONALITY
Closes an open connection to a MSSQL server.
.EXAMPLE
PS>Close-IcingaMSSQLConnection $OpenMSSQLConnection;
.INPUTS
System.Data.SqlClient.SqlConnection
.OUTPUTS
.LINK
https://github.com/Icinga/icinga-powershell-framework
#>
function Close-IcingaMSSQLConnection()
{
param (
[System.Data.SqlClient.SqlConnection]$SqlConnection = $null
);
if ($null -eq $SqlConnection) {
return;
}
Write-IcingaDebugMessage `
-Message 'Closing client connection for endpoint {0}' `
-Objects $SqlConnection;
$SqlConnection.Close();
$SqlConnection.Dispose();
$SqlConnection = $null;
}

View file

@ -0,0 +1,43 @@
<#
.SYNOPSIS
Builds a SQL query
.DESCRIPTION
This Cmdlet will build a SQL query
and returns it as an string.
.FUNCTIONALITY
Build a SQL query
.EXAMPLE
PS>New-IcingaMSSQLCommand -SqlConnection $SqlConnection -SqlQuery "SELECT object_name FROM sys.dm_os_performance_counters";
.PARAMETER SqlConnection
An open SQL connection object e.g. $SqlConnection = Open-IcingaMSSQLConnection -IntegratedSecurity;
.PARAMETER SqlQuery
A SQL query as string.
.INPUTS
System.Data.SqlClient.SqlConnection
System.String
.OUTPUTS
System.Data.SqlClient.SqlCommand
.LINK
https://github.com/Icinga/icinga-powershell-framework
#>
function New-IcingaMSSQLCommand()
{
param (
[System.Data.SqlClient.SqlConnection]$SqlConnection = $null,
[string]$SqlQuery = $null
);
$SqlCommand = New-Object System.Data.SqlClient.SqlCommand;
$SqlCommand.Connection = $SqlConnection;
if ($null -eq $SqlCommand.Connection) {
Exit-IcingaThrowException -ExceptionType 'Input' `
-ExceptionThrown $IcingaExceptions.Inputs.MSSQLCommandMissing `
-CustomMessage 'It seems the -SqlConnection is empty or invalid' `
-Force;
}
$SqlCommand.CommandText = $SqlQuery;
return $SqlCommand;
}

View file

@ -0,0 +1,114 @@
<#
.SYNOPSIS
Opens a connection to a MSSQL server
.DESCRIPTION
This Cmdlet will open a connection to a MSSQL server
and returns that connection object.
.FUNCTIONALITY
Opens a connection to a MSSQL server
.EXAMPLE
PS>Open-IcingaMSSQLConnection -IntegratedSecurity -Address localhost;
.EXAMPLE
PS>Open-IcingaMSSQLConnection -Username Exampleuser -Password (ConvertTo-IcingaSecureString 'examplePassword') -Address 123.125.123.2;
.PARAMETER Username
The username for connecting to the MSSQL database
.PARAMETER Password
The password for connecting to the MSSQL database as secure string
.PARAMETER Address
The IP address or FQDN to the MSSQL server to connect to (default: localhost)
.PARAMETER Port
The port of the MSSQL server/instance to connect to with the provided credentials (default: 1433)
.PARAMETER SqlDatabase
The name of a specific database to connect to. Leave empty to connect "globaly"
.PARAMETER IntegratedSecurity
Allows this plugin to use the credentials of the current PowerShell session inherited by
the user the PowerShell is running with. If this is set and the user the PowerShell is
running with can access to the MSSQL database you will not require to provide username
and password
.OUTPUTS
System.Data.SqlClient.SqlConnection
.LINK
https://github.com/Icinga/icinga-powershell-framework
#>
function Open-IcingaMSSQLConnection()
{
param (
[string]$Username,
[securestring]$Password,
[string]$Address = "localhost",
[int]$Port = 1433,
[string]$SqlDatabase,
[switch]$IntegratedSecurity = $FALSE
);
if ($IntegratedSecurity -eq $FALSE) {
if ([string]::IsNullOrEmpty($Username)) {
Exit-IcingaThrowException `
-ExceptionType 'Input' `
-ExceptionThrown $IcingaExceptions.Inputs.MSSQLCredentialHandling `
-CustomMessage '-Username not set and -IntegratedSecurity is false' `
-Force;
} elseif ($null -eq $Password) {
Exit-IcingaThrowException `
-ExceptionType 'Input' `
-ExceptionThrown $IcingaExceptions.Inputs.MSSQLCredentialHandling `
-CustomMessage '-Password not set and -IntegratedSecurity is false' `
-Force;
}
$Password.MakeReadOnly();
$SqlCredential = New-Object System.Data.SqlClient.SqlCredential($Username, $Password);
}
try {
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection;
$SqlConnection.ConnectionString = "Server=$Address,$Port;";
if ($null -ne $SqlDatabase) {
$SqlConnection.ConnectionString += "Database=$SqlDatabase;";
}
if ($IntegratedSecurity -eq $TRUE) {
$SqlConnection.ConnectionString += "Integrated Security=True;";
}
$SqlConnection.Credential = $SqlCredential;
Write-IcingaDebugMessage `
-Message 'Open client connection for endpoint {0}' `
-Objects $SqlConnection;
$SqlConnection.Open();
} catch {
Exit-IcingaThrowException `
-InputString $_.Exception.Message `
-StringPattern $Username `
-ExceptionType 'Input' `
-ExceptionThrown $IcingaExceptions.Inputs.MSSQLCredentialHandling;
Exit-IcingaThrowException `
-InputString $_.Exception.Message `
-StringPattern 'error: 40' `
-ExceptionType 'Connection' `
-ExceptionThrown $IcingaExceptions.Connection.MSSQLConnectionError;
Exit-IcingaThrowException `
-InputString $_.Exception.Message `
-StringPattern 'error: 0' `
-ExceptionType 'Connection' `
-ExceptionThrown $IcingaExceptions.Connection.MSSQLConnectionError;
Exit-IcingaThrowException `
-InputString $_.Exception.Message `
-StringPattern 'error: 25' `
-ExceptionType 'Connection' `
-ExceptionThrown $IcingaExceptions.Connection.MSSQLConnectionError;
# Last resort
Exit-IcingaThrowException `
-InputString $_.Exception.Message `
-ExceptionType 'Custom' `
-Force;
}
return $SqlConnection;
}

View file

@ -0,0 +1,32 @@
<#
.SYNOPSIS
Executes a SQL query
.DESCRIPTION
This Cmdlet will send a SQL query to a given database and
execute the query and returns the output.
.FUNCTIONALITY
Executes a SQL query
.EXAMPLE
PS> Send-IcingaMSSQLCommand -SqlCommand $SqlCommand;
.PARAMETER SqlCommand
The SQL query which will be executed, e.g. $SqlCommand = New-IcingaMSSQLCommand
.INPUTS
System.Data.SqlClient.SqlCommand
.OUTPUTS
System.Data.DataSet
.LINK
https://github.com/Icinga/icinga-powershell-framework
#>
function Send-IcingaMSSQLCommand()
{
param (
[System.Data.SqlClient.SqlCommand]$SqlCommand = $null
);
$Adapter = New-Object System.Data.SqlClient.SqlDataAdapter $SqlCommand;
$Data = New-Object System.Data.DataSet;
$Adapter.Fill($Data) | Out-Null;
return $Data.Tables;
}