1
0
Fork 0

rules(kubernetes): add example of minimum CPU limit

This commit is contained in:
ssube 2019-06-15 19:25:47 -05:00
parent 07171f1dce
commit deee5c0cbd
6 changed files with 95 additions and 22 deletions

View File

@ -0,0 +1,14 @@
metadata:
name: example
spec:
template:
spec:
containers:
- name: test
resources:
limits:
cpu: 4000m
memory: 5Gi
requests:
cpu: 4000m
memory: 5Gi

View File

@ -0,0 +1,14 @@
metadata:
name: example
spec:
template:
spec:
containers:
- name: test
resources:
limits:
cpu: 2m
memory: 5Mi
requests:
cpu: 1m
memory: 2Mi

View File

@ -1,14 +1,15 @@
rules:
- name: kubernetes-require-resources
- name: kubernetes-resources
level: info
tags:
- cluster-health
- important
nodes:
select: '$.spec.template.spec.containers[*]'
select: '$.spec.template.spec.containers[*]'
filter:
type: object
schema:
check:
type: object
additionalProperties: true
required: [resources]
@ -32,4 +33,31 @@ rules:
cpu:
type: string
memory:
type: string
type: string
- name: kubernetes-resources-minimum-cpu
desc: resource limits are too low
level: debug
tags:
- optional
select: '$.spec.template.spec.containers[*].resources'
filter:
type: object
properties:
limits:
type: object
properties:
cpu:
type: string
pattern: "[0-9]{1,3}m"
check:
type: object
properties:
limits:
type: object
properties:
cpu:
type: string
pattern: "[0-9]{3}m"

View File

@ -1,23 +1,25 @@
import * as Ajv from 'ajv';
import { readFile } from 'fs';
import { JSONPath } from 'jsonpath-plus';
import { intersection } from 'lodash';
import { LogLevel, Logger } from 'noicejs';
import { promisify } from 'util';
import { safeLoad } from 'js-yaml';
import { JSONPath } from 'jsonpath-plus';
import { intersection, isNil } from 'lodash';
import { Logger, LogLevel } from 'noicejs';
import { promisify } from 'util';
import { CONFIG_SCHEMA } from './config';
const readFileSync = promisify(readFile);
export interface Rule {
// metadata
desc: string;
level: LogLevel;
name: string;
nodes: {
filter: string;
select: string;
};
schema: any;
tags: Array<string>;
// data
check: any;
filter: any;
select: string;
}
export interface RuleSelector {
@ -83,19 +85,34 @@ export async function resolveRules(rules: Array<Rule>, selector: RuleSelector):
export function checkRule(rule: Rule, data: any, logger: Logger): boolean {
const ajv = new ((Ajv as any).default)()
const schema = ajv.compile(rule.schema);
const check = ajv.compile(rule.check);
const filter = ajv.compile(rule.filter);
const scopes = JSONPath({
json: data,
path: rule.nodes.select,
path: rule.select,
});
for (const scope of scopes) {
const valid = schema(scope);
if (!valid) {
logger.warn({ errors: schema.errors, item: scope }, 'rule failed on item');
return false;
if (isNil(scopes) || scopes.length === 0) {
logger.debug('no data selected');
return true;
}
for (const item of scopes) {
logger.debug({ item }, 'filtering item');
if (filter(item)) {
logger.debug({ item }, 'checking item')
if (!check(item)) {
logger.warn({
desc: rule.desc,
errors: check.errors,
item,
}, 'rule failed on item');
return false;
}
} else {
logger.debug({ errors: filter.errors, item }, 'skipping item');
}
}
return true;
}