During my workflow creation to check and re-mediate an iSCSI environment and had to create a final WFA command that would create/re-mediate the actual iSCSI connections.
So here are the workflow steps :
1 : Ask for vserver & windows host
2 : Check/Install snapdrive on the host (upgrade will follow)
3 : Check/Start the msiscsi windows service (set to automatic)
4 : Check/Install the multipath-IO feature
5 : Check/Alarm if the windows host has (enough) iscsi ip addresses
6 : Check if the vserver runs iscsi and has (enough) iscsi lifs
7 : Check/Create new mutual chap passwords and store in KeePass database
8 : Check/Create iscsi connections
This post is about step 8.
This step will :
- Get chap passwords from KeePass database (created earlier)
- Get host ip's (checked validity earlier)
- Get vserver ip's (checked validity earlier)
- Check/Create vserver chap authentication (mutual chap)
- Check/Create iscsi target group
- Check/Create iscsi connections (mpio)
Download the dar
Here is the code
param( [Parameter(Mandatory=$true,HelpMessage="Cluster name or ip")] [string]$Cluster, [Parameter(Mandatory=$true,HelpMessage="Vserver name")] [string]$VserverName, [Parameter(Mandatory=$true,HelpMessage="Host IQN Name")] [string]$Iqn, [Parameter(Mandatory=$true,HelpMessage="Computername")] [string]$ComputerName, [Parameter(Mandatory=$true,HelpMessage="Credential name to make a remote connection")] [string]$CredentialName, [Parameter(Mandatory=$true,HelpMessage="Network adddress")] [string]$NetworkAddress, [Parameter(Mandatory=$true,HelpMessage="Subnet mask")] [string]$SubnetMask, [Parameter(Mandatory=$false,HelpMessage="KeePass Database Profile")] [string]$DatabaseProfileName = "wfa_keepass", [Parameter(Mandatory=$true,HelpMessage="KeePass Group Path, relative from root")] [string]$GroupPath, [Parameter(Mandatory=$true,HelpMessage="KeePass Database Path")] [ValidatePattern(“^.*\.kdbx$”)] [string]$DatabasePath, [Parameter(Mandatory=$false,HelpMessage="MasterKey KeePass Credential Name")] [string]$MasterKeyName = "KeePass", [Parameter(Mandatory=$false,HelpMessage="Force remove KeePass config")] [bool]$ForceRemoveConfig, [Parameter(Mandatory=$true,HelpMessage="iSCSI in chap-user name")] [string]$iSCSIinUser, [Parameter(Mandatory=$true,HelpMessage="iSCSI out chap-user name")] [string]$iSCSIoutUser ) function getIpAddresses(){ return Invoke-Command -Session $session -ScriptBlock { [System.Net.NetworkInformation.NetworkInterface]::GetAllNetworkInterfaces() ` | ForEach-Object { $_.GetIPProperties() } ` | Select-Object -ExpandProperty 'UnicastAddresses'; } } function getIscsiConnections(){ return Invoke-Command -Session $session -ScriptBlock {Get-IscsiConnection} } function getIscsiSessions(){ return Invoke-Command -Session $session -ScriptBlock {Get-IscsiSession} } function addIscsiTarget($iscsiOut,$ip,$sourceip,$user,$pass){ $targetfound = $false $target = getIscsiTarget if($target){ if(($target.TargetPortalAddress -eq $sourceip) -and ($target.TargetPortalAddress -eq $ip)){ Get-WFALogger -Info -Message "iscsi target found [$($target.InitiatorPortalAddress) - $($target.TargetPortalAddress)]" $targetfound=$true } } if(-not $targetfound){ Get-WFALogger -Info -Message "adding iscsi target [$sourceip - $ip]" invoke-Command -session $session -script {param($iscsiOut) Set-IscsiChapSecret -ChapSecret $iscsiOut} -ArgumentList $iscsiOut $out = invoke-Command -session $session -script {param($ip,$sourceip,$user,$pass) New-IscsiTargetPortal -TargetPortalAddress $ip -InitiatorPortalAddress $sourceip -AuthenticationType MUTUALCHAP -ChapUsername $user -ChapSecret $pass} -ArgumentList $ip,$sourceip,$user,$pass Get-WFALogger -Info -Message "added iscsi target [$sourceip - $ip]" } } function setIscsiConnection($iscsiOut,$vserverIqn,$ip,$sourceip,$user,$pass){ addIscsiTarget -iscsiOut $iscsiOut -ip $ip -sourceip $sourceip -user $user -pass $pass Get-WFALogger -Info -Message "connecting iscsi target [$sourceip - $ip]" $out = invoke-Command -session $session -script {param($vserverIqn,$ip,$sourceip,$user,$pass) Connect-IscsiTarget -NodeAddress $vserverIqn -TargetPortalAddress $ip -InitiatorPortalAddress $sourceip -AuthenticationType MUTUALCHAP -IsPersistent $true -IsMultipathEnabled $true -ChapUsername $user -ChapSecret $pass} -ArgumentList $vserverIqn,$ip,$sourceip,$user,$pass Get-WFALogger -Info -Message "[connected : $($out.IsConnected)]" } function getIscsiTarget(){ return Invoke-Command -Session $session -ScriptBlock {Get-IscsiTargetPortal} } function createCredentials($username,$password){ $secpasswd = ConvertTo-SecureString $password -AsPlainText -Force return (New-Object System.Management.Automation.PSCredential ($username, $secpasswd)) } function Get-NetworkAddress { param ( [IpAddress]$ip, [IpAddress]$Mask ) $IpAddressBytes = $ip.GetAddressBytes() $SubnetMaskBytes = $Mask.GetAddressBytes() if ($IpAddressBytes.Length -ne $SubnetMaskBytes.Length) { throw "Lengths of IP address and subnet mask do not match." exit 0 } $BroadcastAddress = @() for ($i=0;$i -le 3;$i++) { $BroadcastAddress += $ipAddressBytes[$i]-band $subnetMaskBytes[$i] } $BroadcastAddressString = $BroadcastAddress -Join "." return [IpAddress]$BroadcastAddressString } function Test-IsInSameSubnet { param ( [IpAddress]$ip1, [IpAddress]$ip2, [IpAddress]$mask1, [IpAddress]$mask2 ) $Network1 = Get-NetworkAddress -ip $ip1 -mask $mask1 $Network2 = Get-NetworkAddress -ip $ip2 -mask $mask2 return $Network1.Equals($Network2) } function correctKeePassPath($path){ $path = $path.Trim("/") $rootPath = (Get-KeePassGroup -DatabaseProfileName $DatabaseProfileName -MasterKey $masterPassword | ?{-not $_.ParentGroup}).Name Get-WFALogger -Info -Message "Root path : $rootPath" return "$rootPath/$path" } $ErrorActionPreference = "stop" $iSCSIHosts = @() $iSCSILifs = @() try{ #-------------------------------------------- # Make keepass connection and grab passwords #-------------------------------------------- Import-Module PoShKeePass $masterCred = Get-WfaCredentials $MasterKeyName $masterPassword=$masterCred.Password Get-WfaLogger -info -message "Open connection to keepass db" New-KPConnection -Database $DatabasePath -MasterKey $masterPassword Get-WfaLogger -info -message "Getting keypass profile" $config = Get-KeePassDatabaseConfiguration -DatabaseProfileName $DatabaseProfileName if($config -and $ForceRemoveConfig){ Get-WfaLogger -info -message "Removing keypass profile" Remove-KeePassDatabaseConfiguration -DatabaseProfileName $DatabaseProfileName } if(-not $config){ Get-WfaLogger -info -message "Creating keypass profile" New-KeePassDatabaseConfiguration -DatabaseProfileName $DatabaseProfileName -DatabasePath $DatabasePath -UseMasterKey } # correct path $GroupPath = correctKeePassPath -path $GroupPath # Get Keepass entries Get-WfaLogger -info -message "Check if entry exists" $groups = Get-KeePassGroup -DatabaseProfileName $DatabaseProfileName -MasterKey $masterPassword $entries = Get-KeePassEntry -KeePassEntryGroupPath $GroupPath -AsPlainText -DatabaseProfileName $DatabaseProfileName -MasterKey $masterPassword # get the iscsi entries $iscsiInEntry = $entries | ?{$_.Title -eq $iSCSIinUser -and $_.UserName -eq $iSCSIinUser} $iscsiOutEntry = $entries | ?{$_.Title -eq $iSCSIoutUser -and $_.UserName -eq $iSCSIoutUser} # check the iscsi entries if($iscsiInEntry){ Get-WfaLogger -info -message "Found iSCSIin password" }else{ throw "No iSCSIin entry found in keepass" } if($iscsiOutEntry){ Get-WfaLogger -info -message "Found iSCSIout password" }else{ throw "No iSCSIout entry found in keepass" } # get keepass passwords $iscsiInPwd = $iscsiInEntry.Password $iscsiOutPwd = $iscsiOutEntry.Password #-------------------------------------------- # Make host connection, grab ip's & iscsi connections #-------------------------------------------- # get credentials $mycreds = Get-WfaCredentials $CredentialName # create remote ps session $session = New-PSSession -ComputerName $ComputerName -Credential $mycreds $ipAddresses = getIpAddresses # loop every ipaddres and check if in iscsi range foreach($ip in $IpAddresses){ if($ip.IPv4Mask -ne "0.0.0.0"){ if(Test-IsInSameSubnet -ip1 $ip.Address -ip2 $NetworkAddress -mask1 $ip.IPv4Mask -mask2 $SubnetMask){ $iSCSIHosts+=($ip.Address.IPAddressToString) } } } # get iscsi connection $iscsiConnections = getIscsiConnections $iscsiSessions = getIscsiSessions #-------------------------------------------- # Make vserver connection, check chap and grab lifs #-------------------------------------------- # connect to cluster $clstr = Connect-WfaCluster $Cluster # get vserver iscsi lifs $lifs = Get-NcNetInterface -Vserver $VserverName -DataProtocols iscsi foreach($l in $lifs){ if(Test-IsInSameSubnet -ip1 $l.Address -ip2 $NetworkAddress -mask1 $l.Netmask -mask2 $SubnetMask){ $iSCSILifs+=$l.Address } } # create chap credentials $inCreds = createCredentials -username $iSCSIinUser -password $iscsiInPwd $outCreds = createCredentials -username $iSCSIOutUser -password $iscsiOutPwd # check iscsi credentials $vserverInitiator = Get-NcIscsiInitiatorAuth -Initiator $iqn -VserverContext $VserverName $vserverIqn = (Get-NcIscsiNodeName -VserverContext $VserverName).Name if($vserverInitiator -and ($vserverInitiator.Username -eq $iSCSIinUser)){ Get-WfaLogger -info -message "[vserver] Vserver has valid iscsi credentials [$iqn]" }else{ Get-WfaLogger -info -message "[vserver] Adding vserver iscsi credentials [$iqn -> $iSCSIinUser]" Set-NcIscsiInitiatorAuth -Initiator $iqn -Chap -InboundCredential $inCreds -OutboundCredential $outCreds -VserverContext $VserverName } #-------------------------------------------- # Make iscsi connections #-------------------------------------------- foreach($t in $iSCSILifs){ foreach($i in $iSCSIHosts){ # check if the connection already exists $c = ( $iscsiConnections | ?{$_.InitiatorAddress -eq $i -and $_.TargetAddress -eq $t} ) if($c){ Get-WfaLogger -info -message "[iscsi] valid iscsi connection [$($c.InitiatorAddress) -> $($c.TargetAddress)]" }else{ # setIscsiConnection Get-WfaLogger -warn -message "[iscsi] Missing iscsi connection [$i) -> $($t)]" setIscsiConnection -iscsiOut $iscsiOutPwd -vserverIqn $VserverIqn -ip $t -sourceip $i -user $iSCSIinUser -pass $iscsiInPwd } } } }catch{ throw $_.Exception }finally{ try{ $out = Disconnect-PSSession $session -EA SilentlyContinue $out = Remove-PSSession $session -EA SilentlyContinue }catch{ } }
No comments :
Post a Comment