137 lines
6.4 KiB
PowerShell
137 lines
6.4 KiB
PowerShell
function Connect-AlkamiServiceFabricCluster {
|
|
<#
|
|
.SYNOPSIS
|
|
Initiates a Service Fabric cluster connection, and stores the connection to the global scope for the session.
|
|
No action is taken if you are already connected to the cluster at the provided hostname.
|
|
|
|
.PARAMETER hostname
|
|
The host name of any server in the Service Fabric cluster.
|
|
|
|
.PARAMETER ServerCertificateCommonName
|
|
The common name of the server certificate to authenticate to the cluster with.
|
|
|
|
.PARAMETER CertificateCommonName
|
|
The common name of the server OR client certificate to authenticate to the cluster with.
|
|
#>
|
|
[CmdletBinding()]
|
|
Param(
|
|
[Parameter(Mandatory=$false, ParameterSetName = "WindowsAuth")]
|
|
[Parameter(Mandatory=$false, ParameterSetName = "CertAuth")]
|
|
[string]$Hostname = "localhost",
|
|
[Parameter(Mandatory=$true, ParameterSetName = "CertAuth")]
|
|
[string]$ServerCertificateCommonName,
|
|
[Parameter(Mandatory=$true, ParameterSetName = "CertAuth")]
|
|
[string]$CertificateCommonName
|
|
)
|
|
|
|
$loglead = (Get-LogLeadName);
|
|
|
|
$endpoint = "$($hostname):19000";
|
|
|
|
# Check if we are already connected to this particular cluster endpoint.
|
|
Write-Verbose "$loglead Checking for existing Service Fabric connection.";
|
|
if(($null -ne $Global:ClusterConnection) -and ($Global:ClusterConnection.ConnectionEndpoint -eq $endpoint)) {
|
|
Write-Verbose "$loglead Found existing connection.";
|
|
return;
|
|
}
|
|
|
|
# We can't connect to a cluster if there is no hostname.
|
|
if([string]::IsNullOrWhiteSpace($hostname)) {
|
|
Write-Error "$loglead No hostname provided to connect to.";
|
|
return;
|
|
}
|
|
|
|
# If the connection certificate was not explicitly provided, look it up on the remote machine.
|
|
if([string]::IsNullOrWhiteSpace($CertificateCommonName)) {
|
|
Write-Verbose "$loglead Certificate common name was not specified. Looking up certificate to use from remote machine.";
|
|
|
|
$clusterManifestLocation = "C:\ProgramData\SF\clusterManifest.xml";
|
|
$clusterManifestLocation = Get-UncPath -filePath $clusterManifestLocation -ComputerName $hostname -IgnoreLocalPaths;
|
|
if(!(Test-Path $clusterManifestLocation)) {
|
|
Write-Error "$loglead : Could not find Cluster Manifest config file at '$clusterManifestLocation'. Is this server running Service Fabric?";
|
|
return;
|
|
}
|
|
|
|
# Read the certificate common name to connect to the cluster with.
|
|
$namespace = @{ x = "http://schemas.microsoft.com/2011/01/fabric" };
|
|
$serverCertNode = (Select-Xml -Path $clusterManifestLocation -XPath "//x:ServerCertificate" -Namespace $namespace) | Select-Object -ExpandProperty Node -First 1;
|
|
if(!([string]::IsNullOrWhiteSpace($serverCertNode.X509FindValue))) {
|
|
$CertificateCommonName = $serverCertNode.X509FindValue;
|
|
} else {
|
|
Write-Verbose "$loglead Could not locate a certificate name in the cluster manifest. Falling back to Windows Authentication."
|
|
}
|
|
}
|
|
|
|
# If there is no cert common name, connect with windows authentication.
|
|
if([string]::IsNullOrWhiteSpace($CertificateCommonName)) {
|
|
Write-Verbose "$loglead Opening connection to Service Fabric cluster at endpoint $endpoint with Windows Authentication";
|
|
$connectionResult = (Connect-ServiceFabricCluster -ConnectionEndpoint $endpoint -WindowsCredential);
|
|
} else {
|
|
# Otherwise connect with a certificate.
|
|
Write-Verbose "$loglead Searching for certificate $CertificateCommonName";
|
|
|
|
# Search for the cert in the current user store location.
|
|
$storeLocation = "CurrentUser";
|
|
$cert = (Find-CertificateByName -CommonName $CertificateCommonName -StoreLocation $storeLocation -StoreName My);
|
|
if($null -eq $cert) {
|
|
Write-Verbose "$loglead Could not locate certificate $CertificateCommonName in the user store location."
|
|
}
|
|
|
|
# Search for the cert in the local machine store location.
|
|
if($null -eq $cert) {
|
|
$storeLocation = "LocalMachine";
|
|
$cert = (Find-CertificateByName -CommonName $CertificateCommonName -StoreLocation $storeLocation -StoreName My);
|
|
if($null -eq $cert) {
|
|
Write-Verbose "$loglead Could not locate certificate $CertificateCommonName in the machine store location."
|
|
}
|
|
}
|
|
|
|
# Return out if the certificate could not be located in either store.
|
|
if($null -eq $cert) {
|
|
Write-Error "$loglead Could not locate certificate $CertificateCommonName in the user or machine stores.";
|
|
return;
|
|
}
|
|
|
|
Write-Verbose "$loglead Opening connection to Service Fabric cluster at endpoint $endpoint with certificate $CertificateCommonName";
|
|
|
|
$connectArgs = $null;
|
|
|
|
# If the server cert common name is specified, they are connecting with an explicit server common name + client cert common name
|
|
if(!([string]::IsNullOrWhiteSpace($ServerCertificateCommonName))) {
|
|
$connectArgs = @{
|
|
ConnectionEndpoint = $endpoint;
|
|
X509Credential = $True;
|
|
StoreLocation = "CurrentUser"; # Intentionally only search the CurrentUser store.
|
|
StoreName = "My";
|
|
ServerCommonName = $ServerCertificateCommonName;
|
|
FindType = "FindBySubjectName";
|
|
FindValue = $CertificateCommonName;
|
|
}
|
|
} else {
|
|
# Otherwise we are dealing with an admin cert. Connect using the same certificate for admin/client auth.
|
|
$connectArgs = @{
|
|
ConnectionEndpoint = $endpoint;
|
|
X509Credential = $True;
|
|
StoreLocation = $storeLocation;
|
|
StoreName = "My";
|
|
ServerCertThumbprint = $cert.Thumbprint;
|
|
FindType = 'FindByThumbprint';
|
|
FindValue = $cert.Thumbprint;
|
|
}
|
|
}
|
|
|
|
$connectionResult = (Connect-ServiceFabricCluster @ConnectArgs);
|
|
}
|
|
|
|
$success = $connectionResult[0];
|
|
if(!$success) {
|
|
Write-Error "$loglead Could not open connection to Service Fabric cluster at $endpoint";
|
|
return;
|
|
}
|
|
|
|
# Service fabric sets $ClusterConnection to the local scope.
|
|
# Escalate that scope to the global-scope.
|
|
$Global:ClusterConnection = $ClusterConnection;
|
|
|
|
Write-Host "$loglead Connected to Service Fabric cluster at endpoint $endpoint";
|
|
} |