import * as vscode from 'vscode' ; import { LinterImpl , Syntax } from './linter.impl' ; import { warningOn , childSymbols } from './linter.utils' ; import { flatten } from '../../utils/array' ; export class ResourceLimitsLinter implements LinterImpl { name ( ) { return "resource-limits" ; } async lint ( document , syntax ) { const resources = syntax . load ( document . getText ( ) ) ; if ( ! resources ) { return [ ] ; } const symbols = await syntax . symbolise ( document ) ; if ( ! symbols ) { return [ ] ; } const diagnostics = resources . map ( ( r ) => this . lintOne ( r , symbols ) ) ; return flatten ( ... diagnostics ) ; } private lintOne ( resource , symbols ) { if ( ! resource ) { return [ ] ; } const podSpecPrefix = resource . kind === 'Pod' ? 'spec' : resource . kind === 'Deployment' ? 'spec.template.spec' : undefined ; if ( ! podSpecPrefix ) { return [ ] ; } const containersSymbols = symbols . filter ( ( s ) => s . name === 'containers' && s . containerName === podSpecPrefix ) ; if ( ! containersSymbols ) { return [ ] ; } const warnings = [ ] ; const warnOn = ( symbol , text ) => { warnings . push ( warningOn ( symbol , text ) ) ; } ; for ( const containersSymbol of containersSymbols ) { const imagesSymbols = childSymbols ( symbols , containersSymbol , 'image' ) ; const resourcesSymbols = childSymbols ( symbols , containersSymbol , 'resources' ) ; if ( resourcesSymbols . length < imagesSymbols . length ) { warnOn ( containersSymbol , 'One or more containers do not have resource limits - this could starve other processes' ) ; } for ( const resourcesSymbol of resourcesSymbols ) { const limitsSymbols = childSymbols ( symbols , resourcesSymbol , 'limits' ) ; if ( limitsSymbols . length === 0 ) { warnOn ( resourcesSymbol , 'No resource limits specified for this container - this could starve other processes' ) ; } for ( const limitsSymbol of limitsSymbols ) { const cpuSymbols = childSymbols ( symbols , limitsSymbol , 'cpu' ) ; if ( cpuSymbols . length === 0 ) { warnOn ( limitsSymbol , 'No CPU limit specified for this container - this could starve other processes' ) ; } const memorySymbols = childSymbols ( symbols , limitsSymbol , 'memory' ) ; if ( memorySymbols . length === 0 ) { warnOn ( limitsSymbol , 'No memory limit specified for this container - this could starve other processes' ) ; } } } } return warnings ; } }