Parsing text via piping from 'docker info' output

I have a bash script that parses information from the output of docker commands in this case docker info.
This segment creates a data array for each node (NODE1[0-5], NODE2[0-5], NODE3[0-5], ect…)
I am having trouble splitting out the data in the SERVER pipe.

Current output sample of Powershell Select-String
Data Space Used: 17.7GB
Data Space Total: 102GB
Data Space Available: 84.3GB
Swarm: active
Is Manager: true
Name: servera.mycorp.com

Final output should be an array NODE1 [0]17.7GB [1]102GB [2]84.3GB [3]Active [4]true [5]servera.mycorp.com

Bash code that accomplishes this output

i=1
for j in $(/bin/ssh -q docker@$PRIMENODE "cat /dns/zones/db.192.168.169" | /bin/grep -E -o "([0-9]{1,3 }[\.]){3}[0-9]{1,3}"| /bin/sort -u) ; do
SERVER=($(/bin/ssh -q docker@$j 'docker info' |/bin/grep -E 'Data Space Used|Data Space Total|Data Space Available|Is Manager|Swarm|mycorp.com'| /bin/cut -d ":" -f2|/bin/sed "s/^[ \t]*//"))
IFS=' ' read -ra NODE$i <<< "$j ${SERVER[@]}"
i=$(($i+1))
done

I have gotten as far as pulling the server node IPs and getting the above current output with this Powershell code.

$i=1
$input = ssh -q docker@$PrimeNode "cat /dns/zones/db.192.168.169" | Select-String -Pattern "\d{1,3}(\.\d{1,3}){3}"
foreach($ip in ($input -split "; " | Select-String -Pattern "\d{1,3}(\.\d{1,3}){3}"))
{
$server = ssh -q docker@$ip 'docker info' | Select-String -Pattern (' Data Space Used',' Data Space Total',' Data Space Available','Is Manager','Swarm','mycorp.com')
}

I am having issues figuring out how to split the strings and keep only the part after the split without creating additional extraneous variables and keeping the code clean.
Command output does not produce clean object output and before 2 days ago I have not used Powershell.

Why not convert it to a usable object, rather than a flat array? That output after the first matching operation is pretty close to what ConvertFrom-StringData accepts out of the box.

You could probably do a very simple $server = @(ssh -q docker@$ip ‘docker info’) -replace ‘:’,’=’ | ConvertFrom-StringData

The result would then be an object you could export to CSV, extract specific properties from as needed, pass around to whatever functions you need thereafter, convert to HTML tables, etc., etc.

Thanks, I just looked at the documentation for ConvertFrom-StringData after reading your response. That might do what I need a solve a couple other problems I was foreseeing down the road converting the bash script.

I requires a change of thinking and I have only been working with Powershell for a couple days.

Much appreciated.

  • CategoryInfo : InvalidOperation: (:slight_smile: [ConvertFrom-StringData], PSInvalidOperationException
  • FullyQualifiedErrorId : InvalidOperation,Microsoft.PowerShell.Commands.ConvertFromStringDataCommand

This finally worked. It requires extra variables and extra steps and is not clean. I need to figure out how to increment the $node variable using a counter variable and nest variable names. And I need to figure out how to call the objects $node.Name appears to not be the answer. Powershell is frustrating.

foreach($ip in ($input -split "; " | Select-String -Pattern "\d{1,3}(\.\d{1,3}){3}"))
{
$server = ssh -q docker@$ip 'docker info' | Select-String -Pattern (' Data Space Used',' Data Space Total',' Data Space Available','Is Manager','Swarm','mycorp.com')
$node = @($server) -replace ':','=' 
$node | ConvertFrom-StringData
Write-Host $ip
Write-Host $node
}

Output

Name Value 
---- ----- 
Data Space Used 17.7GB 
Data Space Total 102GB 
Data Space Available 84.3GB 
Swarm active 
Is Manager true 
Name borderlands-i.mycorp.com
192.168.169.50
Data Space Used= 17.7GB Data Space Total= 102GB Data Space Available= 84.3GB Swarm= active Is Manager= true Name= borderlands-i.mycorp.com
Data Space Used 18.77GB 
Data Space Total 102GB 
Data Space Available 83.23GB 
Swarm active 
Is Manager false 
Name borderlands-ii.mycorp.com
192.168.169.51
Data Space Used= 18.77GB Data Space Total= 102GB Data Space Available= 83.23GB Swarm= active Is Manager= false Name= borderlands-ii.mycorp.com
Data Space Used 69.03GB 
Data Space Total 102GB 
Data Space Available 32.98GB 
Swarm active 
Is Manager true 
Name battlefront-i.mycorp.com
192.168.169.200
Data Space Used= 69.03GB Data Space Total= 102GB Data Space Available= 32.98GB Swarm= active Is Manager= true Name= battlefront-i.mycorp.com
Data Space Used 33.56GB 
Data Space Total 102GB 
Data Space Available 68.44GB 
Swarm active 
Is Manager false 
Name battlefront-ii.mycorp.com 
192.168.169.201
Data Space Used= 33.56GB Data Space Total= 102GB Data Space Available= 68.44GB Swarm= active Is Manager= false Name= battlefront-ii.mycorp.com

You’re not storing the result of the conversion. :slight_smile:

$object = $node | ConvertFrom-StringData

$object.Name

That gets me the objects but only for the last ip in the loop. I can not figure out how to increment the variable.

Thanks for the help. It works. Figuring out Powershell will take time.

$PrimeNode = (nslookup dockerhost.mycorp.com 192.168.31.67 | Select-String -Pattern Address | Where-Object LineNumber -eq 5).ToString().Split(' ')[-1]
$i=1
$input = ssh -q docker@$PrimeNode "cat /dns/zones/db.192.168.169" | Select-String -Pattern "\d{1,3}(\.\d{1,3}){3}"
foreach($ip in ($input -split "; " | Select-String -Pattern "\d{1,3}(\.\d{1,3}){3}"))
{
$server = ssh -q docker@$ip 'docker info' | Select-String -Pattern (' Data Space Used',' Data Space Total',' Data Space Available','Is Manager','Swarm','mycorp.com')
$node = @($server) -replace ':',' ='
Set-Variable -Name "node$i" -value ($node | ConvertFrom-StringData)
$i++
Write-Host $ip
}
PS H:\> Write-Host $node1.Name
borderlands-i.mycorp.com

PS H:\> Write-Host $node1.'Data Space Used'
17.7GB

PS H:\> Write-Host $node3.Name
battlefront-i.mycorp.com

PS H:\> Write-Host $node3.'Data Space Used'
69.03GB

 

Nice! I would probably caution against that kind of pattern where you’re generating variable names, though. Better to just use an array so everything is easily accessible from a single variable, and you can access whatever index you like similar to what you’re doing already, but without having a whole bunch of variables so you can easily get every single one out of the one variable as you need them:

https://gist.github.com/vexx32/e7ea9621d0beca06e9e2883f1a43fdb2

In this example you can access the first item in `$NodeList` with `$NodeList[0]` and the last with `$NodeList[-1]`. I also tell PowerShell to output the entire collection at the end, so you can see everything it got. :slight_smile:

That works well but I need to append data to the information based on the nodes from other docker commands and then operations need to be performed on data on a per node basis. That might be doable with a multidimensional array but I believe that will lead to more complexity than needed.

What is not included in the code I posted it that it also gets ‘Node Address’ as part of the pull from ‘docker info’. Later in the script it ‘Is Manager = true’ then it runs another command against the ‘Node Addres’ then appends that information to the proper node based on ‘Name’ (Name is pulled by ‘mycorp.com’ to avoid also pulling ‘Pool Name’).

The final process is more complex than this part. I was just stuck on arrays and the object method actually makes things a little easier since I will not need to remember array locations.