UNPKG

nix-kubernetes

Version:

Kubernetes deployment manager written in nix

144 lines (112 loc) 3.6 kB
'use strict'; const childProcess = require('child_process'); const retry = require('bluebird-retry'); const _ = require('lodash'); const Util = require('../util'); class Kubectl { constructor(options) { this.options = options; } _exec(command, handler) { if (this.options.dryRun) { return childProcess.exec(`${command} --dry-run`, handler); } return childProcess.exec(command, handler); } _command(args) { let cmd = ['kubectl']; if (this.options.context) { cmd.push(`--context ${this.options.context}`); } cmd.push(args); return cmd.join(' '); } exists(ns, type, name) { return Util.run(this._command(`--namespace ${ns} get ${type} ${name}`)) .then(Promise.resolve(true)) .catch(error => { if (error.toString().indexOf('not found') > -1) { return Promise.resolve(false); } throw error; }); } get(ns, type, name) { return Util.run(this._command(`--namespace ${ns} get -o json ${type} ${name}`)) .then(result => { return JSON.parse(result); }) .catch(error => { if (error.toString().indexOf('not found') > -1) { return Promise.resolve(false); } throw error; }); } listAllNamespaces(types) { return Util.run(this._command(`get -o json ${types.join(',')} --all-namespaces`)) .then(result => JSON.parse(result)) .then(result => result.items) .catch(error => { if (error.toString().indexOf('not found') > -1) { return Promise.resolve(false); } throw error; }); } delete(ns, type, name) { return Util.run(this._command(`--namespace ${ns} delete ${type} ${name}`)); } deleteByLabels(ns, type, labels) { const selector = _.map(labels, (value, name) => `${name}=${value}`).join(','); return Util.run(this._command(`--namespace ${ns} delete ${type} -l ${selector}`)); } wait(ns, type, name, options, condition) { return retry(() => { return this.get(ns, type, name).then(result => { return condition(result); }); }, options); } deploy(ns, type, name, resource) { console.log(`deploying${this.options.dryRun ? " (dry-run)" : ""}:`, type, name); return this.exists(ns, type, name).then(exists => { return new Promise((res, rej) => { let child; let handler = (error, stdout) => { if (error) { return rej(error); } res(stdout); }; const append = this.options.append || ''; if (exists && type === 'StatefulSet') { delete resource.spec.volumeClaimTemplates; } child = this._exec(this._command(`--namespace ${ns} apply -f - ${append}`), handler); child.stdin.write(JSON.stringify(resource)); child.stdin.end(); }); }); } rollingUpdate(ns, name, resource) { return new Promise((res, rej) => { let handler = (error, stdout) => { if (error) { return rej(error); } res(stdout); }; const append = this.options.append || ''; const child = this._exec(this._command(`--namespace ${ns} rolling-update ${name} -f - ${append}`), handler); child.stdout.on('data', data => process.stdout.write(data)); child.stdin.write(JSON.stringify(resource)); child.stdin.end(); }); } logs(ns, name, handler) { const child = childProcess.exec(this._command(`--namespace ${ns} logs -f ${name}`), handler); return child; } } module.exports = Kubectl;