From aa5e95f28ab1d9ae6ed412414ad741aa07c47b13 Mon Sep 17 00:00:00 2001 From: jbjohnso Date: Tue, 21 May 2013 13:00:43 +0000 Subject: [PATCH] Commit powershell files to windows style line wrap in case of notepad git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/branches/2.8@16377 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd --- .../xcat/netboot/windows/xCAT.format.ps1xml | 248 +++--- .../share/xcat/netboot/windows/xCAT.psm1 | 812 +++++++++--------- 2 files changed, 528 insertions(+), 532 deletions(-) diff --git a/xCAT-server/share/xcat/netboot/windows/xCAT.format.ps1xml b/xCAT-server/share/xcat/netboot/windows/xCAT.format.ps1xml index 6a14ecbb2..9a346c1f0 100644 --- a/xCAT-server/share/xcat/netboot/windows/xCAT.format.ps1xml +++ b/xCAT-server/share/xcat/netboot/windows/xCAT.format.ps1xml @@ -1,124 +1,124 @@ - - - - - children - - MergedxCATNodeData - - - NodeRange - - - - - 24 - - - - - - - - - - Description - - - Data - - - - - - - - children - - MergedxCATSimpleNodeData - - - NodeRange - - - - - - - - - - - - Data - - - - - - - - children - - xCATSimpleNodeData - - - - - 12 - - - - - - - - - - Node - - - Data - - - - - - - - children - - xCATNodeData - - - - - 12 - - - 24 - - - - - - - - - - Node - - - Description - - - Data - - - - - - - - - + + + + + children + + MergedxCATNodeData + + + NodeRange + + + + + 24 + + + + + + + + + + Description + + + Data + + + + + + + + children + + MergedxCATSimpleNodeData + + + NodeRange + + + + + + + + + + + + Data + + + + + + + + children + + xCATSimpleNodeData + + + + + 12 + + + + + + + + + + Node + + + Data + + + + + + + + children + + xCATNodeData + + + + + 12 + + + 24 + + + + + + + + + + Node + + + Description + + + Data + + + + + + + + + diff --git a/xCAT-server/share/xcat/netboot/windows/xCAT.psm1 b/xCAT-server/share/xcat/netboot/windows/xCAT.psm1 index 288bb706a..8a579454d 100644 --- a/xCAT-server/share/xcat/netboot/windows/xCAT.psm1 +++ b/xCAT-server/share/xcat/netboot/windows/xCAT.psm1 @@ -1,408 +1,404 @@ -# IBM(c) 2013 EPL license http://www.eclipse.org/legal/epl-v10.html -# This function specifically validates that the peer we are talking to is signed by the xCAT blessed CA and no other CA -Function Import-xCATConfig ($credentialPackage) { - $shell = New-Object -com shell.application - $credentialPackage = $credentialPackage -replace '^\.\\','' - if (-not $credentialPackage -match '\\') { - $mypath = Get-Location - $credentialPackage = $mypath.Path + $credentialPackage - } - $credpkg = $shell.namespace($credentialPackage) - $randname = [System.IO.Path]::GetRandomFileName() - Push-Location - mkdir $env:temp+"\"+$randname - Set-Location $env:temp+"\"+$randname - $tmpdir = $shell.namespace((Get-Location).Path) - $tmpdir - $tmpdir.CopyHere($credpkg.items(),0x14) - if (!(Test-Path HKCU:\Software\xCAT)) { - mkdir HKCU:\Software\xCAT - } - if (Test-Path xcat.cfg) { - $cfgdata=Get-Content xcat.cfg - $keyvalue = $cfgdata.Split("=") - $servername = $keyvalue[1] - Set-ItemProperty HKCU:\Software\xCAT servername $servername - } - if (Test-Path ca.pem) { - ImportxCATCA ca.pem - } - if (Test-Path user.pfx) { - SetxCATClientCertificate user.pfx - } - Pop-Location -} -Function VerifyxCATCert ($sender, $cert, $chain, $polerrs) { - if ($polerrs -ne "None" -and $polerrs -ne "RemoteCertificateChainErrors") { return $false } #if the overall policy suggests rejection, go with it - #why do we tolerate RemoteCertificateChainErrors? Because we are going to check specifically for the CA configured for this xCAT installation - #we chose not to add xCAT's CA to the root store, as that implies the OS should trust xCAT's CA for non-xCAT related things. That is madness. - #Of course, that's the madness typical with x509, but we need not propogate the badness... - #we are measuring something more specific than 'did any old CA sign this', we specifically want to assue the signer CA is xCAT's - if (Test-Path HKCU:\Software\xCAT) { - $mythumb=Get-ItemProperty HKCU:\Software\xCAT - } else { - $mythumb=Get-ItemProperty HKLM:\Software\xCAT - } - foreach ($cert in $chain.chainElements) { - if ($mythumb.cacertthumb.Equals($cert.Certificate.thumbprint)) { - return $true - } - } - return $false -} - -#we import the xCAT certificate authority into the appropriate scope. -#It's not trusted by system policy, but our overidden verify function will find it. Too bad MS doesn't allow us custom store names under the user -#repository for whatever reason. We'll just 'import' it every session from file, which is harmless to do multiple times -#this isn't quite as innocuous as the openssl mechanisms to do this sort of thing, but it's as close as I could figure to get -Function ImportxCATCA ( $certpath ) { - $xcatstore = New-Object System.Security.Cryptography.X509Certificates.X509Store("xCAT","CurrentUser") - $certpath -replace '^\.\\','' - if (-not $certpath -match '\\') { - $mypath=Get-Location - $certpath = $mypath.Path + $certpath - } - $cacert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($certpath) - $xcatstore.Open([System.Security.Cryptography.X509Certificates.OpenFlags]'Readwrite') - $xcatstore.Add($xcatcacert) - Set-ItemProperty HKCU:\Software\xCAT cacertthumb $xcatcacert.thumbprint -} - -#this removes the xCAT CA from trust store, if user wishes to explicitly remove xCAT key post deploy -#A good idea for appliances that want to not show weird stuff. The consequences of not calling it are harmless: a useless extra public cert -#in admin's x509 cert store -Function RemovexCATCA { - $mythumb=Get-ItemProperty HKCU:\Software\xCAT - rm cert:\CurrentUser\My\$mythumb.cacertthumb -} - -#specify a client certificate to use in pfx format -Function SetxCATClientCertificate ( $pfxPath ) { - $pfxPath = $pfxPath -replace '^\.\\','' - if (-not $pxfPath -match '\\') { - $mypath=Get-Location - $pfxPath = $mypath.Path + $pfxPath - } - - $xcatstore = New-Object System.Security.Cryptography.X509Certificates.X509Store("xCAT","CurrentUser") - $xcatclientcert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($pfxpath) - $xcatstore.Add($xcatclientcert) - Set-ItemProperty HKCU:\Software\xCAT usercertthumb $xcatclientcert.thumbprint -} -Function RemovexCATClientCertificate { - SetxCATClientCertificate($pfxpath) - $mythumb=Get-ItemProperty HKCU:\Software\xCAT - if (!$mythumb) { - $mythumb=Get-ItemProperty HKLM:\Software\xCAT - } - rm cert:\currentuser\my\$mythumb.usercertthumb -} - -#key here is that we might have two certificates: -#-one intended to identify the system that was deployed by xcat -#-one intended to identify the user to do things like 'rpower' -#however, user will just have to control it by calling Set-xCATClientCertificate on the file for now -#TODO: if user wants password protected PFX file, we probably would want to import it once and retain thumb across sessions... -Function SelectxCATClientCert ($sender, $targetHost, $localCertificates, $remoteCertificate,$acceptableIssuers) { - if (!(Test-Path HKCU:\Software\xCAT)) { #in this case, we might be operating in system context for install instrumentation - $myreg=Get-ItemProperty HKLM:\Software\xCAT - if ($myreg) { #confirmed that we have a machine level authentication setup to fall back upon - $mycertthumb=$myreg.usercertthumb - Get-Item cert:\LocalMachine\xCAT\$mycertthumb - } - } else { - $myreg = Get-ItemProperty HKCU:\Software\xCAT - $mythumb=(Get-ItemProperty HKCU:\Software\xCAT).usercertthumb - Get-Item cert:\CurrentUser\My\$mythumb - } -} -Function Set-xCATServer { - Param( - [Parameter(Mandatory=$true)] $xCATServer - ) - Set-ItemProperty HKCU:\Software\xCAT serveraddress $xCATServer -} -Function Connect-xCAT { - Param( - $mgtServer, - $mgtServerPort=3001, - $mgtServerAltName - ) - if (! $mgtServer) { - if (Test-Path HKCU:\Software\xCAT) { - $mgtServer=(Get-ItemProperty HKCU:\Software\xCAT).serveraddress - if (! $mgtServer) { - $mgtServer=(Get-ItemProperty HKCU:\Software\xCAT).servername - } - } else { - if (! $mgtServer) { - $mgtServer=(Get-ItemProperty HKLM:\Software\xCAT).serveraddress - } - if (! $mgtServer) { - $mgtServer=(Get-ItemProperty HKLM:\Software\xCAT).servername - } - } - } - if (! $mgtServerAltName) { - if (Test-Path HKCU:\Software\xCAT) { - $mgtServerAltName=(Get-ItemProperty HKCU:\Software\xCAT).servername - } elseif (Test-Path HKLM:\Software\xCAT) { #node reporting command - $mgtServerAltName=(Get-ItemProperty HKLM:\Software\xCAT).servername - } - } - $script:xcatconnection = New-Object Net.Sockets.TcpClient($mgtServer,$mgtServerPort) - if (! $script:xcatconnection) { - return $false - } - $verifycallback = Get-Content Function:\VerifyxCATCert - $certselect = Get-Content Function:\SelectxCATClientCert - $script:xcatstream = $script:xcatconnection.GetStream() - $haveclientcert=0 - if (Test-Path HKCU:\Software\xCAT) { - $xcreg=Get-ItemProperty HKCU:\Software\xCAT - if ($xcreg.usercertthumb) { - $haveclientcert=1 - } - } elseif (Test-Path HKLM:\Software\xCAT) { #intended for localsystem context for node->xCAT calls - $xcreg=Get-ItemProperty HKLM:\Software\xCAT - if ($xcreg.usercertthumb) { - $haveclientcert=1 - } - } - if ($haveclientcert) { - $script:securexCATStream = New-Object System.Net.Security.SSLStream($script:xcatstream,$false,$verifycallback,$certselect) - } else { - $script:securexCATStream = New-Object System.Net.Security.SSLStream($script:xcatstream,$false,$verifycallback) - } - $script:securexCATStream.AuthenticateAsClient($mgtServerAltName) - $script:xcatwriter = New-Object System.IO.StreamWriter($script:securexCATStream) - $script:xcatreader = New-Object System.IO.StreamReader($script:securexCATStream) - $true -} - -Function Get-NodeInventory { - Param( - [parameter(ValueFromPipeLine=$true)] $nodeRange, - [parameter(ValueFromRemainingArguments=$true)] $inventoryType - ) - $pipednr=@($input) - if ($pipednr) { $nodeRange = $pipednr } - $xcatrequest=@{'command'='rinv';'noderange'=$nodeRange;'args'=@($inventoryType)} - Send-xCATCommand($xcatrequest) -} -Function Get-NodeBeacon { - Param( - [parameter(ValueFromPipeLine=$true)] $nodeRange - ) - $pipednr=@($input) - if ($pipednr) { $nodeRange = $pipednr } - $xcatrequest=@{'command'='rbeacon';'noderange'=$nodeRange;'args'=@('stat')} - Send-xCATCommand($xcatrequest) -} -Function Set-NodeBeacon { - Param( - [parameter(ValueFromPipeLine=$true)] $nodeRange, - $newBeaconState - ) - $pipednr=@($input) - if ($pipednr) { $nodeRange = $pipednr } - $xcatrequest=@{'command'='rbeacon';'noderange'=$nodeRange;'args'=@($newBeaconState)} - Send-xCATCommand($xcatrequest) -} -Function Get-NodePower { - Param( - [parameter(Position=0,ValueFromPipeLine=$true)] $nodeRange - ) - $pipednr=@($input) - if ($pipednr) { $nodeRange = $pipednr } - $xcatrequest=@{'command'='rpower';'noderange'=$nodeRange;'args'=@('stat')} - Send-xCATCommand($xcatrequest) -} -Function Merge-xCATData { #xcoll attempt - $groupeddata=$input|Group-Object -Property "node" - $hashbyoutput=@{} - foreach ($nodedata in $groupeddata) { - $gdata= NewMergedxCATData $nodedata.Group - if ($hashbyoutput.Contains($gdata.stringcontent)) { - $hashbyoutput.Get_Item($gdata.stringcontent).NodeList += $gdata.NodeList - } else { - $hashbyoutput.Add($gdata.stringcontent,$gdata) - } - } - $distinctoutput=$hashbyoutput.GetEnumerator() - foreach ($collateddata in $distinctoutput) { - $findata = $collateddata.Value - $findata.NodeRange=[string]::Join(",",$findata.NodeList) - $findata = $findata |select-object -excludeproperty NodeRangeHint,stringcontent * - $mobjname = 'MergedxCATSimpleNodeData' - foreach ($do in $findata.dataObjects) { - if ($do.ErrorData) { - $mobjname='MergedxCATNodeErrorData' - break - } elseif ($do.description) { - $mobjname='MergedxCATNodeData' - break - } - } - foreach ($do in $findata.dataObjects) { - $do|Add-Member -MemberType NoteProperty -Name NodeRange -Value $findata.NodeRange - $do.PSObject.TypeNames.Insert(0,$mobjname) - $do - } - } - -} -Function Set-NodePower { - Param( - [parameter(ValueFromPipeLine=$true)] $nodeRange, - [parameter(HelpMessage="The power action to perform (on/off/boot/reset)")] $powerState="stat" - ) - $pipednr=@($input) - if ($pipednr) { $nodeRange = $pipednr } - $xcatrequest=@{'command'='rpower';'noderange'=$nodeRange;'args'=@($powerState)} - Send-xCATCommand($xcatrequest) -} -Function Get-Nodes { - Param( - [parameter(Position=0,ValueFromPipeLine=$true)] $nodeRange, - [parameter(ValueFromRemainingArguments=$true)] $tableAndColumn - ) - $pipednr=@($input) - if ($pipednr) { $nodeRange = $pipednr } - $xcatrequest=@{'command'='nodels';'noderange'=$nodeRange;'args'=@($tableAndColumn)} - Send-xCATCommand($xcatrequest) -} -Function Get-NodeVitals { - Param( - [parameter(Position=0,ValueFromPipeLine=$true)] $nodeRange, - [parameter(ValueFromRemainingArguments=$true)] $vitalTypes="all" - ) - $pipednr=@($input) - if ($pipednr) { $nodeRange = $pipednr } - $xcatrequest=@{'command'='rvitals';'noderange'=$nodeRange;'args'=@($vitalTypes)} - Send-xCATCommand($xcatrequest) -} -Function Send-xCATCommand { - Param( - $xcatRequest - ) - if (!(Connect-xCAT)) { return } - $requestxml = "`n`t"+$xcatRequest.command+"`n" - if ($xcatRequest.noderange) { - if ($xcatRequest.noderange.PSObject.TypeNames[0] -eq "xCATNodeData") { - $xcatRequest.noderange = $xcatRequest.noderange.Node - } - if ($xcatRequest.noderange -is [System.Array]) { #powershell wants to arrayify commas because it can't make up its mind - #whether it's a scripting language or a shell language, try to undo the - #damage - $nrparts=@() - foreach ($nr in $xcatRequest.noderange) { - if ($nr -is [System.String]) { - $nrparts += $nr - } elseif ($nr.PSObject.TypeNames[0] -like "xCAT*Node*Data") { - $nrparts += $nr.Node - } elseif ($nr.PSObject.TypeNames[0] -like "Merge*xCAT*Node*Data") { - $nrparts += $nr.NodeRange - } - } - $xcatRequest.noderange=[string]::Join(",",$nrparts); - } - $requestxml = $requestxml + "`t"+$xcatRequest.noderange+"`n" - } - foreach ($arg in $xcatRequest.args) { - if ($arg) { - if ($arg -is [System.Array]) { - $arg=[string]::join(",",$arg); - } - $requestxml = $requestxml + "`t"+$arg+"`n" - } - } - $requestxml = $requestxml + "`n" - $script:xcatwriter.WriteLine($requestxml) - $script:xcatwriter.Flush() - $serverdone=0 - while (! $serverdone -and $script:xcatreader) { - $responsexml="" - $lastline="" - while ($lastline -ne $null -and ! $lastline.Contains("") -and $script:xcatreader) { - $lastline = $script:xcatreader.ReadLine() - $responsexml = $responsexml + $lastline - } - [xml]$response = $responsexml - foreach ($elem in $response.xcatresponse.node) { - NewxCATDataFromXmlElement $elem -NodeRangeHint $xcatRequest.noderange - } - foreach ($elem in $response.xcatresponse.error) { - Write-Error $elem - } - #$response.xcatresponse.node.name - #$response.xcatresponse.node.data - if ($response.xcatresponse.serverdone -ne $null) { $serverdone=1 } - } -} - -Function NewMergedxCATData { #takes an arbitrary number of nodeData objects and spits out one - Param( - $nodeData - ) - $myobj = @{} - $myobj.dataObjects=@() - $myobj.NodeList = @($nodeData[0].Node) - $myobj.NodeRangeHint = $nodeData[0].NodeRangeHint - $myobj.stringcontent = "" - $myobj.NodeRange = "" - foreach ($data in $nodeData) { - $rangedata = $data|select-object -ExcludeProperty Node,NodeRangeHint * - foreach ($dataseg in $rangedata) { - if ($dataseg.ErrorData) { $myobj.stringcontent += "ERROR: "+$dataseg.ErrorData } - $myobj.stringcontent += $dataseg.Description+": "+$dataseg.Data+"`n" - } - $myobj.dataObjects = $myobj.dataObjects + $rangedata - } - $newobj = New-Object -TypeName PSObject -Prop $myobj - $newobj.PSObject.TypeNames.Insert(0,'TempxCATNodeRangeData') - return $newobj -} -Function NewxCATDataFromXmlElement { - Param( - $xmlElement, - $NodeRangeHint - ) - $myprops = @{} - $objname = 'xCATSimpleNodeData' - if ($NodeRangeHint) { #hypothetically, 'xcoll' implementation might find this handy - $myprops.NodeRangeHint=$NodeRangeHint - } - if ($xmlElement.name) { - $myprops.Node=$xmlElement.name - } - if ($xmlElement.data.desc) { - $objname = 'xCATNodeData' - $myprops.Description=$xmlElement.data.desc - } - if ($xmlElement.data.contents) { - $myprops.Data=$xmlElement.data.contents - } else { - $myprops.Data="" - } - if ($xmlElement.error) { - $objname = 'xCATNodeErrorData' - $errstr= $xmlElement.name + ": " + $xmlElement.error - Write-Error $errstr - $myprops.ErrorData=$xmlElement.error - } - $myobj=New-Object -TypeName PSObject -Prop $myprops - $myobj.PSObject.TypeNames.Insert(0,$objname) - return $myobj -} -New-Alias -name rpower -value Set-NodePower -New-Alias -name rvitals -value Get-Nodevitals -New-Alias -name rinv -value Get-NodeInventory -New-Alias -name rbeacon -value Set-NodeBeacon -New-Alias -name nodels -value Get-Nodes -New-Alias -name xcoll -value Merge-xCATData -Export-ModuleMember -function *-* -Alias * - - - - +# IBM(c) 2013 EPL license http://www.eclipse.org/legal/epl-v10.html +# This function specifically validates that the peer we are talking to is signed by the xCAT blessed CA and no other CA +Function Import-xCATConfig ($credentialPackage) { + $shell = New-Object -com shell.application + $credentialPackage = $credentialPackage -replace '^\.\\','' + if (-not $credentialPackage -match '\\') { + $mypath = Get-Location + $credentialPackage = $mypath.Path + $credentialPackage + } + $credpkg = $shell.namespace($credentialPackage) + $randname = [System.IO.Path]::GetRandomFileName() + Push-Location + mkdir $env:temp+"\"+$randname + Set-Location $env:temp+"\"+$randname + $tmpdir = $shell.namespace((Get-Location).Path) + $tmpdir + $tmpdir.CopyHere($credpkg.items(),0x14) + if (!(Test-Path HKCU:\Software\xCAT)) { + mkdir HKCU:\Software\xCAT + } + if (Test-Path xcat.cfg) { + $cfgdata=Get-Content xcat.cfg + $keyvalue = $cfgdata.Split("=") + $servername = $keyvalue[1] + Set-ItemProperty HKCU:\Software\xCAT servername $servername + } + if (Test-Path ca.pem) { + ImportxCATCA ca.pem + } + if (Test-Path user.pfx) { + SetxCATClientCertificate user.pfx + } + Pop-Location +} +Function VerifyxCATCert ($sender, $cert, $chain, $polerrs) { + if ($polerrs -ne "None" -and $polerrs -ne "RemoteCertificateChainErrors") { return $false } #if the overall policy suggests rejection, go with it + #why do we tolerate RemoteCertificateChainErrors? Because we are going to check specifically for the CA configured for this xCAT installation + #we chose not to add xCAT's CA to the root store, as that implies the OS should trust xCAT's CA for non-xCAT related things. That is madness. + #Of course, that's the madness typical with x509, but we need not propogate the badness... + #we are measuring something more specific than 'did any old CA sign this', we specifically want to assue the signer CA is xCAT's + if (Test-Path HKCU:\Software\xCAT) { + $mythumb=Get-ItemProperty HKCU:\Software\xCAT + } else { + $mythumb=Get-ItemProperty HKLM:\Software\xCAT + } + foreach ($cert in $chain.chainElements) { + if ($mythumb.cacertthumb.Equals($cert.Certificate.thumbprint)) { + return $true + } + } + return $false +} + +#we import the xCAT certificate authority into the appropriate scope. +#It's not trusted by system policy, but our overidden verify function will find it. Too bad MS doesn't allow us custom store names under the user +#repository for whatever reason. We'll just 'import' it every session from file, which is harmless to do multiple times +#this isn't quite as innocuous as the openssl mechanisms to do this sort of thing, but it's as close as I could figure to get +Function ImportxCATCA ( $certpath ) { + $xcatstore = New-Object System.Security.Cryptography.X509Certificates.X509Store("xCAT","CurrentUser") + $certpath -replace '^\.\\','' + if (-not $certpath -match '\\') { + $mypath=Get-Location + $certpath = $mypath.Path + $certpath + } + $cacert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($certpath) + $xcatstore.Open([System.Security.Cryptography.X509Certificates.OpenFlags]'Readwrite') + $xcatstore.Add($xcatcacert) + Set-ItemProperty HKCU:\Software\xCAT cacertthumb $xcatcacert.thumbprint +} + +#this removes the xCAT CA from trust store, if user wishes to explicitly remove xCAT key post deploy +#A good idea for appliances that want to not show weird stuff. The consequences of not calling it are harmless: a useless extra public cert +#in admin's x509 cert store +Function RemovexCATCA { + $mythumb=Get-ItemProperty HKCU:\Software\xCAT + rm cert:\CurrentUser\My\$mythumb.cacertthumb +} + +#specify a client certificate to use in pfx format +Function SetxCATClientCertificate ( $pfxPath ) { + $pfxPath = $pfxPath -replace '^\.\\','' + if (-not $pxfPath -match '\\') { + $mypath=Get-Location + $pfxPath = $mypath.Path + $pfxPath + } + + $xcatstore = New-Object System.Security.Cryptography.X509Certificates.X509Store("xCAT","CurrentUser") + $xcatclientcert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($pfxpath) + $xcatstore.Add($xcatclientcert) + Set-ItemProperty HKCU:\Software\xCAT usercertthumb $xcatclientcert.thumbprint +} +Function RemovexCATClientCertificate { + SetxCATClientCertificate($pfxpath) + $mythumb=Get-ItemProperty HKCU:\Software\xCAT + if (!$mythumb) { + $mythumb=Get-ItemProperty HKLM:\Software\xCAT + } + rm cert:\currentuser\my\$mythumb.usercertthumb +} + +#key here is that we might have two certificates: +#-one intended to identify the system that was deployed by xcat +#-one intended to identify the user to do things like 'rpower' +#however, user will just have to control it by calling Set-xCATClientCertificate on the file for now +#TODO: if user wants password protected PFX file, we probably would want to import it once and retain thumb across sessions... +Function SelectxCATClientCert ($sender, $targetHost, $localCertificates, $remoteCertificate,$acceptableIssuers) { + if (!(Test-Path HKCU:\Software\xCAT)) { #in this case, we might be operating in system context for install instrumentation + $myreg=Get-ItemProperty HKLM:\Software\xCAT + if ($myreg) { #confirmed that we have a machine level authentication setup to fall back upon + $mycertthumb=$myreg.usercertthumb + Get-Item cert:\LocalMachine\xCAT\$mycertthumb + } + } else { + $myreg = Get-ItemProperty HKCU:\Software\xCAT + $mythumb=(Get-ItemProperty HKCU:\Software\xCAT).usercertthumb + Get-Item cert:\CurrentUser\My\$mythumb + } +} +Function Set-xCATServer { + Param( + [Parameter(Mandatory=$true)] $xCATServer + ) + Set-ItemProperty HKCU:\Software\xCAT serveraddress $xCATServer +} +Function Connect-xCAT { + Param( + $mgtServer, + $mgtServerPort=3001, + $mgtServerAltName + ) + if (! $mgtServer) { + if (Test-Path HKCU:\Software\xCAT) { + $mgtServer=(Get-ItemProperty HKCU:\Software\xCAT).serveraddress + if (! $mgtServer) { + $mgtServer=(Get-ItemProperty HKCU:\Software\xCAT).servername + } + } else { + if (! $mgtServer) { + $mgtServer=(Get-ItemProperty HKLM:\Software\xCAT).serveraddress + } + if (! $mgtServer) { + $mgtServer=(Get-ItemProperty HKLM:\Software\xCAT).servername + } + } + } + if (! $mgtServerAltName) { + if (Test-Path HKCU:\Software\xCAT) { + $mgtServerAltName=(Get-ItemProperty HKCU:\Software\xCAT).servername + } elseif (Test-Path HKLM:\Software\xCAT) { #node reporting command + $mgtServerAltName=(Get-ItemProperty HKLM:\Software\xCAT).servername + } + } + $script:xcatconnection = New-Object Net.Sockets.TcpClient($mgtServer,$mgtServerPort) + if (! $script:xcatconnection) { + return $false + } + $verifycallback = Get-Content Function:\VerifyxCATCert + $certselect = Get-Content Function:\SelectxCATClientCert + $script:xcatstream = $script:xcatconnection.GetStream() + $haveclientcert=0 + if (Test-Path HKCU:\Software\xCAT) { + $xcreg=Get-ItemProperty HKCU:\Software\xCAT + if ($xcreg.usercertthumb) { + $haveclientcert=1 + } + } elseif (Test-Path HKLM:\Software\xCAT) { #intended for localsystem context for node->xCAT calls + $xcreg=Get-ItemProperty HKLM:\Software\xCAT + if ($xcreg.usercertthumb) { + $haveclientcert=1 + } + } + if ($haveclientcert) { + $script:securexCATStream = New-Object System.Net.Security.SSLStream($script:xcatstream,$false,$verifycallback,$certselect) + } else { + $script:securexCATStream = New-Object System.Net.Security.SSLStream($script:xcatstream,$false,$verifycallback) + } + $script:securexCATStream.AuthenticateAsClient($mgtServerAltName) + $script:xcatwriter = New-Object System.IO.StreamWriter($script:securexCATStream) + $script:xcatreader = New-Object System.IO.StreamReader($script:securexCATStream) + $true +} + +Function Get-NodeInventory { + Param( + [parameter(ValueFromPipeLine=$true)] $nodeRange, + [parameter(ValueFromRemainingArguments=$true)] $inventoryType + ) + $pipednr=@($input) + if ($pipednr) { $nodeRange = $pipednr } + $xcatrequest=@{'command'='rinv';'noderange'=$nodeRange;'args'=@($inventoryType)} + Send-xCATCommand($xcatrequest) +} +Function Get-NodeBeacon { + Param( + [parameter(ValueFromPipeLine=$true)] $nodeRange + ) + $pipednr=@($input) + if ($pipednr) { $nodeRange = $pipednr } + $xcatrequest=@{'command'='rbeacon';'noderange'=$nodeRange;'args'=@('stat')} + Send-xCATCommand($xcatrequest) +} +Function Set-NodeBeacon { + Param( + [parameter(ValueFromPipeLine=$true)] $nodeRange, + $newBeaconState + ) + $pipednr=@($input) + if ($pipednr) { $nodeRange = $pipednr } + $xcatrequest=@{'command'='rbeacon';'noderange'=$nodeRange;'args'=@($newBeaconState)} + Send-xCATCommand($xcatrequest) +} +Function Get-NodePower { + Param( + [parameter(Position=0,ValueFromPipeLine=$true)] $nodeRange + ) + $pipednr=@($input) + if ($pipednr) { $nodeRange = $pipednr } + $xcatrequest=@{'command'='rpower';'noderange'=$nodeRange;'args'=@('stat')} + Send-xCATCommand($xcatrequest) +} +Function Merge-xCATData { #xcoll attempt + $groupeddata=$input|Group-Object -Property "node" + $hashbyoutput=@{} + foreach ($nodedata in $groupeddata) { + $gdata= NewMergedxCATData $nodedata.Group + if ($hashbyoutput.Contains($gdata.stringcontent)) { + $hashbyoutput.Get_Item($gdata.stringcontent).NodeList += $gdata.NodeList + } else { + $hashbyoutput.Add($gdata.stringcontent,$gdata) + } + } + $distinctoutput=$hashbyoutput.GetEnumerator() + foreach ($collateddata in $distinctoutput) { + $findata = $collateddata.Value + $findata.NodeRange=[string]::Join(",",$findata.NodeList) + $findata = $findata |select-object -excludeproperty NodeRangeHint,stringcontent * + $mobjname = 'MergedxCATSimpleNodeData' + foreach ($do in $findata.dataObjects) { + if ($do.ErrorData) { + $mobjname='MergedxCATNodeErrorData' + break + } elseif ($do.description) { + $mobjname='MergedxCATNodeData' + break + } + } + foreach ($do in $findata.dataObjects) { + $do|Add-Member -MemberType NoteProperty -Name NodeRange -Value $findata.NodeRange + $do.PSObject.TypeNames.Insert(0,$mobjname) + $do + } + } + +} +Function Set-NodePower { + Param( + [parameter(ValueFromPipeLine=$true)] $nodeRange, + [parameter(HelpMessage="The power action to perform (on/off/boot/reset)")] $powerState="stat" + ) + $pipednr=@($input) + if ($pipednr) { $nodeRange = $pipednr } + $xcatrequest=@{'command'='rpower';'noderange'=$nodeRange;'args'=@($powerState)} + Send-xCATCommand($xcatrequest) +} +Function Get-Nodes { + Param( + [parameter(Position=0,ValueFromPipeLine=$true)] $nodeRange, + [parameter(ValueFromRemainingArguments=$true)] $tableAndColumn + ) + $pipednr=@($input) + if ($pipednr) { $nodeRange = $pipednr } + $xcatrequest=@{'command'='nodels';'noderange'=$nodeRange;'args'=@($tableAndColumn)} + Send-xCATCommand($xcatrequest) +} +Function Get-NodeVitals { + Param( + [parameter(Position=0,ValueFromPipeLine=$true)] $nodeRange, + [parameter(ValueFromRemainingArguments=$true)] $vitalTypes="all" + ) + $pipednr=@($input) + if ($pipednr) { $nodeRange = $pipednr } + $xcatrequest=@{'command'='rvitals';'noderange'=$nodeRange;'args'=@($vitalTypes)} + Send-xCATCommand($xcatrequest) +} +Function Send-xCATCommand { + Param( + $xcatRequest + ) + if (!(Connect-xCAT)) { return } + $requestxml = "`n`t"+$xcatRequest.command+"`n" + if ($xcatRequest.noderange) { + if ($xcatRequest.noderange.PSObject.TypeNames[0] -eq "xCATNodeData") { + $xcatRequest.noderange = $xcatRequest.noderange.Node + } + if ($xcatRequest.noderange -is [System.Array]) { #powershell wants to arrayify commas because it can't make up its mind + #whether it's a scripting language or a shell language, try to undo the + #damage + $nrparts=@() + foreach ($nr in $xcatRequest.noderange) { + if ($nr -is [System.String]) { + $nrparts += $nr + } elseif ($nr.PSObject.TypeNames[0] -like "xCAT*Node*Data") { + $nrparts += $nr.Node + } elseif ($nr.PSObject.TypeNames[0] -like "Merge*xCAT*Node*Data") { + $nrparts += $nr.NodeRange + } + } + $xcatRequest.noderange=[string]::Join(",",$nrparts); + } + $requestxml = $requestxml + "`t"+$xcatRequest.noderange+"`n" + } + foreach ($arg in $xcatRequest.args) { + if ($arg) { + if ($arg -is [System.Array]) { + $arg=[string]::join(",",$arg); + } + $requestxml = $requestxml + "`t"+$arg+"`n" + } + } + $requestxml = $requestxml + "`n" + $script:xcatwriter.WriteLine($requestxml) + $script:xcatwriter.Flush() + $serverdone=0 + while (! $serverdone -and $script:xcatreader) { + $responsexml="" + $lastline="" + while ($lastline -ne $null -and ! $lastline.Contains("") -and $script:xcatreader) { + $lastline = $script:xcatreader.ReadLine() + $responsexml = $responsexml + $lastline + } + [xml]$response = $responsexml + foreach ($elem in $response.xcatresponse.node) { + NewxCATDataFromXmlElement $elem -NodeRangeHint $xcatRequest.noderange + } + foreach ($elem in $response.xcatresponse.error) { + Write-Error $elem + } + #$response.xcatresponse.node.name + #$response.xcatresponse.node.data + if ($response.xcatresponse.serverdone -ne $null) { $serverdone=1 } + } +} + +Function NewMergedxCATData { #takes an arbitrary number of nodeData objects and spits out one + Param( + $nodeData + ) + $myobj = @{} + $myobj.dataObjects=@() + $myobj.NodeList = @($nodeData[0].Node) + $myobj.NodeRangeHint = $nodeData[0].NodeRangeHint + $myobj.stringcontent = "" + $myobj.NodeRange = "" + foreach ($data in $nodeData) { + $rangedata = $data|select-object -ExcludeProperty Node,NodeRangeHint * + foreach ($dataseg in $rangedata) { + if ($dataseg.ErrorData) { $myobj.stringcontent += "ERROR: "+$dataseg.ErrorData } + $myobj.stringcontent += $dataseg.Description+": "+$dataseg.Data+"`n" + } + $myobj.dataObjects = $myobj.dataObjects + $rangedata + } + $newobj = New-Object -TypeName PSObject -Prop $myobj + $newobj.PSObject.TypeNames.Insert(0,'TempxCATNodeRangeData') + return $newobj +} +Function NewxCATDataFromXmlElement { + Param( + $xmlElement, + $NodeRangeHint + ) + $myprops = @{} + $objname = 'xCATSimpleNodeData' + if ($NodeRangeHint) { #hypothetically, 'xcoll' implementation might find this handy + $myprops.NodeRangeHint=$NodeRangeHint + } + if ($xmlElement.name) { + $myprops.Node=$xmlElement.name + } + if ($xmlElement.data.desc) { + $objname = 'xCATNodeData' + $myprops.Description=$xmlElement.data.desc + } + if ($xmlElement.data.contents) { + $myprops.Data=$xmlElement.data.contents + } else { + $myprops.Data="" + } + if ($xmlElement.error) { + $objname = 'xCATNodeErrorData' + $errstr= $xmlElement.name + ": " + $xmlElement.error + Write-Error $errstr + $myprops.ErrorData=$xmlElement.error + } + $myobj=New-Object -TypeName PSObject -Prop $myprops + $myobj.PSObject.TypeNames.Insert(0,$objname) + return $myobj +} +New-Alias -name rpower -value Set-NodePower +New-Alias -name rvitals -value Get-Nodevitals +New-Alias -name rinv -value Get-NodeInventory +New-Alias -name rbeacon -value Set-NodeBeacon +New-Alias -name nodels -value Get-Nodes +New-Alias -name xcoll -value Merge-xCATData +Export-ModuleMember -function *-* -Alias *