Last active
February 10, 2021 18:00
-
-
Save kadamwhite/01b15fc34c118d6c5e1f89ede3448af5 to your computer and use it in GitHub Desktop.
Node script to print out all running docker containers by IP
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env node | |
const child_process = require( 'child_process' ); | |
/** | |
* Execute a command as a spawned process. | |
* | |
* @param {String} command A bash command string, excluding arguments. | |
* @param {String[]} args An array of argument strings for the provided command. | |
*/ | |
const spawn = ( command, args ) => { | |
const output = []; | |
return new Promise( ( resolve, reject ) => { | |
const spawnedProcess = child_process.spawn( command, args ); | |
spawnedProcess.stdout.on( 'data', ( message ) => { | |
output.push( message.toString() ); | |
} ); | |
spawnedProcess.on( 'error', err => reject( err ) ); | |
spawnedProcess.on( 'close', ( code, signal ) => { | |
if ( code ) { | |
reject(); | |
return; | |
} | |
resolve( output.join( '\n' ) ); | |
} ); | |
} ); | |
}; | |
/** | |
* Use child_process to run `docker ps` and `docker inspect` commands to return | |
* a JSON object with the ID, name, and IPs of all running containers. | |
* | |
* @async | |
* @returns {Object[]} Array of { name, id, ips } container objects. | |
*/ | |
const getContainers = async () => { | |
try { | |
const psOutput = await spawn( 'docker', [ | |
'ps', | |
'--format', | |
'{{.ID}},{{.Names}}', | |
] ); | |
const containers = psOutput.trim().split( '\n' ) | |
.map( ( line ) => { | |
const [ id, name ] = line.split( ',' ); | |
return { id, name }; | |
} ); | |
for ( let container of containers ) { | |
// Hat-tip https://www.freecodecamp.org/news/how-to-get-a-docker-container-ip-address-explained-with-examples/ | |
const ips = await spawn( 'docker', [ | |
'inspect', | |
'--format', | |
'{{.NetworkSettings.IPAddress}},{{range .NetworkSettings.Networks}}{{.IPAddress}},{{end}}', | |
container.id, | |
] ); | |
container.ips = ips.split( ',' ) | |
.map( ( str ) => str.trim().replace( '<no value>', 'No IP' ) ) | |
.filter( Boolean ) | |
.sort(); | |
} | |
return containers; | |
} catch ( e ) { | |
throw e; | |
} | |
}; | |
const containersPromise = getContainers(); | |
/** | |
* Given a URL, return the object defining the associated container. | |
* | |
* If no container is using an IP which appears in the URL, return null. | |
* | |
* @async | |
* @param {String} url A url e.g. http://172.18.0.8:8080 | |
* @returns {Object|null} Container object { id, name, ips }, or else null. | |
*/ | |
const getContainerByURL = async ( url ) => { | |
const containers = await containersPromise; | |
for ( let container of containers ) { | |
for ( let ip of container.ips ) { | |
if ( url.indexOf( ip ) > -1 ) { | |
return container; | |
} | |
} | |
} | |
return null; | |
} | |
/** | |
* Pretty-print the container namess by IP address. | |
* | |
* @async | |
* @returns {String} Nicely formatted table of containers by IP. | |
*/ | |
const describeContainers = async () => { | |
const containers = await containersPromise; | |
const longestIPLength = containers.reduce( ( max, container ) => Math.max( max, container.ips.join( ', ' ).length ), 0 ); | |
const longestNameLength = containers.reduce( ( max, container ) => Math.max( max, container.name.length ), 0 ); | |
const pad = ( str, length ) => { | |
while ( str.length < length ) { | |
str = `${ str } `; | |
} | |
return str; | |
} | |
const sortedContainers = containers | |
.map( ( { ips, id, name } ) => `${ | |
pad( `${ ips.join( ', ' ) }`, longestIPLength ) | |
} ${ | |
pad( name, longestNameLength ) | |
} ${ id }` ) | |
.sort(); | |
return `\nDocker Containers by IP:\n\n${ | |
`${ pad( 'IPs', longestIPLength ) } ${ pad( 'Name', longestNameLength ) } ID` | |
}\n${ sortedContainers.join( '\n' ) }`; | |
}; | |
if ( require.main === module ) { | |
( async () => { | |
console.log( await describeContainers() ); | |
} )(); | |
} | |
module.exports = { | |
getContainers, | |
getContainerByURL, | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment