Add support for running routines via command line

This commit is contained in:
garrettmills
2020-08-13 20:28:23 -05:00
parent afb35ebad8
commit f5b84b530c
33 changed files with 396 additions and 5 deletions

View File

@@ -0,0 +1,73 @@
const Directive = require('flitter-cli/Directive')
const path = require('path')
class Rollcall extends Directive {
static get services() {
return [...super.services, 'configs', 'hosts']
}
static options() {
return [
'--hosts -h {host file} | path to the host definition file'
]
}
static name() {
return 'rollcall'
}
static help() {
return 'Ping the configured hosts to determine if we can access them'
}
async handle(app, argv) {
const host_path = this.option('hosts')
if ( host_path ) {
try {
// Override the host config externally
const host_conf = require(path.resolve(host_path))
if (typeof host_conf === 'object') {
this.configs.canonical_items.hosts = host_conf
this.info('Loaded host definition file.')
} else {
this.error('Invalid host definition file!')
}
} catch (e) {
this.error('Invalid host definition file!')
this.output.debug(e)
}
}
const successes = []
const failures = []
const host_config = this.configs.get('hosts')
const hostnames = Object.keys(host_config)
for ( const name of hostnames ) {
this.info(`Pinging ${name}...`)
try {
const host = this.hosts.get(name)
const is_alive = await host.is_alive()
if ( !is_alive ) {
failures.push(name)
this.error('Unable to ping host and verify execution.')
} else {
successes.push(name)
this.success('Connected to host and verified execution.')
}
} catch(e) {
failures.push(name)
this.error('Unable to ping host and verify execution.')
this.output.debug(e)
}
}
this.hosts.close()
this.info(`Successfully pinged ${successes.length} host(s).`)
if ( failures.length > 0 ) this.info(`Unable to ping ${failures.length} host(s): ${failures.join(', ')}`)
}
}
module.exports = exports = Rollcall

View File

@@ -0,0 +1,100 @@
const Directive = require('flitter-cli/Directive')
const path = require('path')
class Routine extends Directive {
static get services() {
return [...super.services, 'configs', 'hosts', 'routines']
}
static options() {
return [
'--hosts -h {host file} | path to the host definition file',
'--target -t {host name} | the host to run the routine on',
'--routine -r {routine file} | path to the routine definition file',
'--type -t {run type} | how to execute the routine: checks | apply'
]
}
static name() {
return 'routine'
}
static help() {
return 'Run the specified routine file'
}
async handle(app, argv) {
const host_path = this.option('hosts')
const routine_path = this.option('routine')
const target_host = this.option('target')
const run_type = this.option('type')
if ( host_path ) {
try {
// Override the host config externally
const host_conf = require(path.resolve(host_path))
if (typeof host_conf === 'object') {
this.configs.canonical_items.hosts = host_conf
this.info('Loaded host definition file.')
} else {
this.error('Invalid host definition file!')
}
} catch (e) {
this.error('Invalid host definition file!')
this.output.debug(e)
}
}
// loaded_from_cli
const host = this.hosts.get(target_host)
if ( !host ) {
this.error('Invalid host name. Unable to find configuration for host with that name.')
return
}
if ( !['checks', 'apply'].includes(run_type) ) {
this.error('Invalid run type. Must be one of: checks, apply')
return
}
if ( routine_path ) {
try {
// Override the routine config externally
const routine_conf = require(path.resolve(routine_path))
if (typeof routine_conf === 'object') {
routine_conf.hosts = [target_host]
routine_conf.type = run_type
if ( Array.isArray(routine_conf.steps) ) {
routine_conf.steps = routine_conf.steps.map(step => {
step.host = target_host
return step
})
}
this.configs.canonical_items['routines:loaded_from_cli'] = routine_conf
this.info('Loaded routine definition file.')
} else {
this.error('Invalid routine definition file!')
}
} catch (e) {
this.error('Invalid routine definition file!')
this.output.debug(e)
}
} else {
this.error('Missing required parameter: --routine')
return
}
const routine = await this.routines.get('loaded_from_cli')
try {
const result = await routine.execute(true)
} catch (e) {
this.output.error(e)
}
this.hosts.close()
}
}
module.exports = exports = Routine