@leverege/build-tools 2.4.9 → 2.5.0-beta.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -1
- package/lib/server/build-tools.js +144 -0
- package/lib/server/getfbcfg.js +25 -0
- package/lib/server/getjson.js +74 -0
- package/lib/server/npm-scripts/postinstall.js +19 -0
- package/lib/server/overwhelm.js +373 -0
- package/lib/server/repo-init/Config.js +45 -0
- package/lib/server/repo-init/RepoInit.js +176 -0
- package/lib/server/repo-init/config.tgz +0 -0
- package/lib/server/repo-init/gitter/Gitter.js +241 -0
- package/lib/server/repo-init/gitter/RepoHosting.js +106 -0
- package/lib/server/repo-init/gitter/index.js +9 -0
- package/lib/server/repo-init/index.js +6 -0
- package/lib/server/repo-init/templates/Templates.js +279 -0
- package/lib/server/repo-init/templates/ToBuildSpec.js +95 -0
- package/lib/server/repo-init/templates/index.js +9 -0
- package/lib/server/repo-init/utils/Shell.js +102 -0
- package/lib/server/repo-init/utils/VersionCheck.js +82 -0
- package/lib/server/repo-init/utils/index.js +67 -0
- package/lib/web/build-tools.js +144 -0
- package/lib/web/getfbcfg.js +25 -0
- package/lib/web/getjson.js +74 -0
- package/lib/web/npm-scripts/postinstall.js +19 -0
- package/lib/web/overwhelm.js +373 -0
- package/package.json +30 -29
- package/src/bash-funcs +61 -0
- package/src/build-tools.js +137 -0
- package/src/{getfbcfg → getfbcfg.js} +7 -6
- package/src/getjson.js +74 -0
- package/src/helmdn +1 -1
- package/src/npm-scripts/postinstall.js +17 -0
- package/src/{overwhelm → overwhelm.js} +83 -83
- package/lib/server/packleate/Packleator.js +0 -280
- package/lib/server/packleate/index.js +0 -98
- package/lib/server/packleate/logo-ansi.js +0 -17
- package/lib/web/packleate/Packleator.js +0 -623
- package/lib/web/packleate/index.js +0 -163
- package/lib/web/packleate/logo-ansi.js +0 -3
- package/src/getjson +0 -48
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
|
|
4
|
+
const chalk = require('chalk');
|
|
5
|
+
|
|
6
|
+
const cliArgs = require('command-line-args');
|
|
7
|
+
|
|
8
|
+
const cliHelp = require('command-line-usage');
|
|
9
|
+
|
|
10
|
+
const fs = require('fs');
|
|
11
|
+
|
|
12
|
+
const npmRegistryFetch = require('npm-registry-fetch');
|
|
13
|
+
|
|
14
|
+
const path = require('path');
|
|
15
|
+
|
|
16
|
+
const semverLt = require('semver/functions/lt');
|
|
17
|
+
/* eslint-disable no-console */
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
const optionList = [// Use optionList to tie into the Usage statements
|
|
21
|
+
{
|
|
22
|
+
name: 'root',
|
|
23
|
+
type: Boolean,
|
|
24
|
+
default: false,
|
|
25
|
+
description: 'returns the root of the build-tools installation'
|
|
26
|
+
}, {
|
|
27
|
+
name: 'bashfun',
|
|
28
|
+
type: Boolean,
|
|
29
|
+
default: false,
|
|
30
|
+
descriptions: 'returns path to a script to source for common bash functions'
|
|
31
|
+
}, {
|
|
32
|
+
name: 'help',
|
|
33
|
+
type: Boolean,
|
|
34
|
+
default: false,
|
|
35
|
+
description: 'display this help screen'
|
|
36
|
+
}, {
|
|
37
|
+
name: 'latest',
|
|
38
|
+
type: Boolean,
|
|
39
|
+
default: false,
|
|
40
|
+
description: 'verifies the latest build-tools are installed'
|
|
41
|
+
}, {
|
|
42
|
+
name: 'version',
|
|
43
|
+
type: Boolean,
|
|
44
|
+
default: false,
|
|
45
|
+
description: 'returns the build-tools repo version'
|
|
46
|
+
}, {
|
|
47
|
+
name: 'verbose',
|
|
48
|
+
alias: 'v',
|
|
49
|
+
type: Boolean,
|
|
50
|
+
default: false,
|
|
51
|
+
description: 'emit additional info at run time'
|
|
52
|
+
}];
|
|
53
|
+
const sections = [{
|
|
54
|
+
header: 'Something to go in the Header',
|
|
55
|
+
content: 'Generate something {italic very} important.'
|
|
56
|
+
}, {
|
|
57
|
+
header: 'Options',
|
|
58
|
+
optionList
|
|
59
|
+
}];
|
|
60
|
+
const args = cliArgs(optionList, {
|
|
61
|
+
partial: true
|
|
62
|
+
});
|
|
63
|
+
const help = cliHelp(sections);
|
|
64
|
+
const repoRoot = path.dirname(__dirname);
|
|
65
|
+
|
|
66
|
+
const thisPackage = require(`${repoRoot}/package.json`);
|
|
67
|
+
|
|
68
|
+
const thisVersion = thisPackage.version;
|
|
69
|
+
|
|
70
|
+
if (args.root) {
|
|
71
|
+
console.log(repoRoot);
|
|
72
|
+
process.exit(0);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (args.bashfun) {
|
|
76
|
+
console.log(`${repoRoot}/src/bash-funcs`);
|
|
77
|
+
process.exit(0);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const checkForLatest = async (pkg = '@leverege/build-tools') => {
|
|
81
|
+
const getToken = () => {
|
|
82
|
+
const tokenFile = `${process.env.HOME}/.npmrc`;
|
|
83
|
+
|
|
84
|
+
if (!fs.existsSync(tokenFile)) {
|
|
85
|
+
console.error(`Cannot find token file ${tokenFile}`);
|
|
86
|
+
process.exit(1);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
try {
|
|
90
|
+
const tokenLine = fs.readFileSync(tokenFile).toString();
|
|
91
|
+
const tokenRegX = new RegExp('.*registry.npmjs.org\\/:\\w+=+(.*)');
|
|
92
|
+
const tokenStr = tokenLine.match(tokenRegX);
|
|
93
|
+
|
|
94
|
+
if (!tokenStr) {
|
|
95
|
+
console.error(`\n***ERROR: malformed npm token in ${tokenFile}\n`);
|
|
96
|
+
process.exit(1);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return tokenLine.match(tokenRegX)[1];
|
|
100
|
+
} catch (err) {
|
|
101
|
+
console.error(err);
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
try {
|
|
106
|
+
const list = await npmRegistryFetch.json(pkg, {
|
|
107
|
+
'//registry.npmjs.org/:token': getToken()
|
|
108
|
+
});
|
|
109
|
+
return list['dist-tags'].latest;
|
|
110
|
+
} catch (err) {
|
|
111
|
+
console.log(err);
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
if (args.latest) {
|
|
116
|
+
checkForLatest().then(latestVersion => {
|
|
117
|
+
if (semverLt(thisVersion, latestVersion)) {
|
|
118
|
+
console.log(chalk.white`
|
|
119
|
+
Update available ${chalk.grey(thisVersion)} \u2b62 ${chalk.green(latestVersion)}
|
|
120
|
+
Run ${chalk.cyan('npm i -g @leverege/build-tools')} to update
|
|
121
|
+
`);
|
|
122
|
+
process.exit(1);
|
|
123
|
+
} else {
|
|
124
|
+
process.exit(0);
|
|
125
|
+
}
|
|
126
|
+
}).catch(err => {});
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (args.version) {
|
|
130
|
+
console.log(`build-tools version ${thisVersion}`);
|
|
131
|
+
process.exit(0);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (args.help) {
|
|
135
|
+
console.log(help);
|
|
136
|
+
process.exit(0);
|
|
137
|
+
}
|
|
138
|
+
/* eslint-disable no-underscore-dangle */
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
if (args._unknown) {
|
|
142
|
+
console.log(`Hey Bozo, WTF am I supposed to do with ${args._unknown}?`);
|
|
143
|
+
process.exit(1);
|
|
144
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* This script parses a firebase config into something useful.
|
|
5
|
+
*/
|
|
6
|
+
"use strict";
|
|
7
|
+
|
|
8
|
+
const stdbuf = [];
|
|
9
|
+
/* eslint-disable no-console */
|
|
10
|
+
|
|
11
|
+
process.stdin.on('data', d => {
|
|
12
|
+
stdbuf.push(d);
|
|
13
|
+
}).on('end', () => {
|
|
14
|
+
const rawCfg = stdbuf.join('').replace(/["\n\r]/g, '');
|
|
15
|
+
const keyVals = rawCfg.match(/\{(.*)\}/)[1].split(',');
|
|
16
|
+
const lastLine = keyVals.length - 1;
|
|
17
|
+
console.log('{');
|
|
18
|
+
|
|
19
|
+
for (let i = 0; i <= lastLine; i++) {
|
|
20
|
+
const kv = keyVals[i].trim().split(' ');
|
|
21
|
+
console.log(` "${kv[0].replace(/:/, '')}": "${kv[1]}"${i < lastLine ? ',' : ''}`);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
console.log('}');
|
|
25
|
+
}).setEncoding('utf8');
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* This script will allow the user to grab a value from a JSON file and
|
|
5
|
+
* optionally apply a regular expression to it. Given this test.json file:
|
|
6
|
+
*
|
|
7
|
+
* {
|
|
8
|
+
* "name": "@leverege/packagename",
|
|
9
|
+
* "main": "lib/index.js"
|
|
10
|
+
* }
|
|
11
|
+
*
|
|
12
|
+
* and invoking as:
|
|
13
|
+
* ./getjson --file ./test.json --key name --regex "^@\w{3}"
|
|
14
|
+
*
|
|
15
|
+
* will yield an output of: @lev
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Get a command line switch parser.
|
|
20
|
+
*/
|
|
21
|
+
"use strict";
|
|
22
|
+
|
|
23
|
+
const fs = require('fs');
|
|
24
|
+
|
|
25
|
+
const cliArgs = require('command-line-args');
|
|
26
|
+
|
|
27
|
+
const cliHelp = require('command-line-usage');
|
|
28
|
+
/* eslint-disable no-console */
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
const optionList = [// Use optionList to tie into the Usage statements
|
|
32
|
+
{
|
|
33
|
+
name: 'file',
|
|
34
|
+
type: String,
|
|
35
|
+
alias: 'f',
|
|
36
|
+
description: 'file to parse JSON from'
|
|
37
|
+
}, {
|
|
38
|
+
name: 'key',
|
|
39
|
+
type: String,
|
|
40
|
+
alias: 'k',
|
|
41
|
+
description: 'JSON key whose value to grab'
|
|
42
|
+
}, {
|
|
43
|
+
name: 'regex',
|
|
44
|
+
type: String,
|
|
45
|
+
alias: 'r',
|
|
46
|
+
description: 'regular expression to apply to the value'
|
|
47
|
+
}];
|
|
48
|
+
const sections = [{
|
|
49
|
+
header: 'JSON variable fetching script',
|
|
50
|
+
content: ` This script is intended to give shell scripts a simple JSON
|
|
51
|
+
parsing capability.`
|
|
52
|
+
}, {
|
|
53
|
+
header: 'Options',
|
|
54
|
+
optionList
|
|
55
|
+
}];
|
|
56
|
+
const args = cliArgs(optionList, {
|
|
57
|
+
partial: true
|
|
58
|
+
});
|
|
59
|
+
const help = cliHelp(sections);
|
|
60
|
+
|
|
61
|
+
if (!args.file) {
|
|
62
|
+
console.error('\n***ERROR: Missing a --file param\n');
|
|
63
|
+
console.log(help);
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
try {
|
|
68
|
+
const json = JSON.parse(fs.readFileSync(args.file, 'utf8'));
|
|
69
|
+
const value = json[args.key];
|
|
70
|
+
const match = new RegExp(args.regex || '.*').exec(value);
|
|
71
|
+
console.log(match ? match[match.length - 1] : '');
|
|
72
|
+
} catch (e) {
|
|
73
|
+
console.log(e);
|
|
74
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
|
|
4
|
+
const execa = require('execa');
|
|
5
|
+
|
|
6
|
+
const fs = require('fs');
|
|
7
|
+
|
|
8
|
+
const untarConfigTarball = async (subdir, tarball) => {
|
|
9
|
+
if (fs.existsSync(subdir)) {
|
|
10
|
+
process.chdir(subdir);
|
|
11
|
+
await execa('tar', ['xf', tarball]);
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const awaiter = async (subdir, tarball) => {
|
|
16
|
+
await untarConfigTarball(subdir, tarball);
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
awaiter('lib/server/repo-init', 'config.tgz');
|
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/* eslint-disable no-console */
|
|
4
|
+
"use strict";
|
|
5
|
+
|
|
6
|
+
const chalk = require('chalk');
|
|
7
|
+
|
|
8
|
+
const cliArgs = require('command-line-args'); // const cliHelp = require( 'command-line-usage' )
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
const exec = require('child_process').execSync;
|
|
12
|
+
|
|
13
|
+
const fs = require('fs');
|
|
14
|
+
|
|
15
|
+
const glob = require('glob');
|
|
16
|
+
|
|
17
|
+
const parse = require('parse-gitignore');
|
|
18
|
+
|
|
19
|
+
const ask = require('readline-sync');
|
|
20
|
+
|
|
21
|
+
const YAML = require('js-yaml');
|
|
22
|
+
|
|
23
|
+
const optionsDefinitions = [
|
|
24
|
+
/* eslint-disable no-multi-spaces */
|
|
25
|
+
{
|
|
26
|
+
name: 'context',
|
|
27
|
+
alias: 'x',
|
|
28
|
+
type: String,
|
|
29
|
+
default: ''
|
|
30
|
+
}, {
|
|
31
|
+
name: 'section',
|
|
32
|
+
alias: 's',
|
|
33
|
+
type: String,
|
|
34
|
+
default: 'default'
|
|
35
|
+
}, {
|
|
36
|
+
name: 'key',
|
|
37
|
+
alias: 'k',
|
|
38
|
+
type: String
|
|
39
|
+
}, {
|
|
40
|
+
name: 'export',
|
|
41
|
+
alias: 'e',
|
|
42
|
+
type: Boolean,
|
|
43
|
+
default: false
|
|
44
|
+
}, {
|
|
45
|
+
name: 'continue',
|
|
46
|
+
alias: 'c',
|
|
47
|
+
type: Boolean,
|
|
48
|
+
default: false
|
|
49
|
+
}, {
|
|
50
|
+
name: 'checkctx',
|
|
51
|
+
alias: 't',
|
|
52
|
+
type: Boolean,
|
|
53
|
+
default: false
|
|
54
|
+
}, {
|
|
55
|
+
name: 'fetchctx',
|
|
56
|
+
alias: 'f',
|
|
57
|
+
type: Boolean,
|
|
58
|
+
default: false
|
|
59
|
+
}, {
|
|
60
|
+
name: 'verbose',
|
|
61
|
+
alias: 'v',
|
|
62
|
+
type: Boolean,
|
|
63
|
+
default: false
|
|
64
|
+
}
|
|
65
|
+
/* eslint-enable no-multi-spaces */
|
|
66
|
+
];
|
|
67
|
+
const args = cliArgs(optionsDefinitions); // The kubernetes context is equal to the git branch name.
|
|
68
|
+
|
|
69
|
+
const gitBranch = require('git-branch').sync();
|
|
70
|
+
|
|
71
|
+
const context = args.context || gitBranch;
|
|
72
|
+
|
|
73
|
+
if (context === 'master') {
|
|
74
|
+
console.log('***ERROR: master context is forbidden; change to a different branch\n\n');
|
|
75
|
+
process.exit(1);
|
|
76
|
+
} // Load the default values and then overlay with the project specific yaml
|
|
77
|
+
// values. This supports the notion of this type of approach in the
|
|
78
|
+
// overwhelm yaml settings:
|
|
79
|
+
// default:
|
|
80
|
+
// GCE_MACHINE : "n1-standard-2"
|
|
81
|
+
//
|
|
82
|
+
// my-project:
|
|
83
|
+
// GCE_MACHINE : "n1-highcpu-8"
|
|
84
|
+
//
|
|
85
|
+
// fashion, but it is advised not to set a default region with this
|
|
86
|
+
// approach in order to keep us cognizant of exactly where a cluster is
|
|
87
|
+
// being formed.
|
|
88
|
+
//
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
const yaml = YAML.safeLoad(fs.readFileSync('overwhelm.yaml', 'utf-8'));
|
|
92
|
+
const over = yaml.default;
|
|
93
|
+
let cfgs = yaml[context]; // If we just need to check context return 0 if cfgs exists, else error.
|
|
94
|
+
|
|
95
|
+
if (args.checkctx) {
|
|
96
|
+
process.exit(!cfgs);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (!cfgs) {
|
|
100
|
+
console.log(`***ERROR: Unknown context => [${context}]\n`);
|
|
101
|
+
console.log(' Known k8s contexts are:');
|
|
102
|
+
Object.keys(yaml).forEach(key => {
|
|
103
|
+
if (key !== 'default') {
|
|
104
|
+
console.log(` ${key}`);
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
console.log(`Add a section into overwhelm.yaml for ${context}\n\n`);
|
|
108
|
+
process.exit(1);
|
|
109
|
+
} // Check to see if we are deriving from another configuration.
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
if (cfgs['PROJECT_BASE']) {
|
|
113
|
+
const baseName = cfgs['PROJECT_BASE'];
|
|
114
|
+
const tempCfgs = cfgs;
|
|
115
|
+
cfgs = yaml[baseName];
|
|
116
|
+
Object.keys(tempCfgs).forEach(key => {
|
|
117
|
+
cfgs[key] = tempCfgs[key];
|
|
118
|
+
});
|
|
119
|
+
console.log('PROJECT_BASE still under evaluation');
|
|
120
|
+
console.log('\n cfgs=', cfgs);
|
|
121
|
+
process.exit(1); // XXX HERE
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
Object.keys(cfgs).forEach(key => {
|
|
125
|
+
over[key] = cfgs[key] || over[key];
|
|
126
|
+
}); // Expand any variables that reference other variable settings. A perfect
|
|
127
|
+
// example of where this is useful is in the setting of a PROJECT_NAME and
|
|
128
|
+
// a PROJECT_ID. Most of the time these values are identical, which is why
|
|
129
|
+
// this setting exists in the default section:
|
|
130
|
+
// default:
|
|
131
|
+
// PROJECT_ID : ${PROJECT_NAME}
|
|
132
|
+
//
|
|
133
|
+
// However, in the case of projects like Siren Marine, this is the more
|
|
134
|
+
// likely setup due to legacy naming schemes:
|
|
135
|
+
// sire-marine:
|
|
136
|
+
// PROJECT_NAME : siren-marine
|
|
137
|
+
// PROJECT_ID : prod-rt-data
|
|
138
|
+
//
|
|
139
|
+
|
|
140
|
+
const varErrors = [];
|
|
141
|
+
Object.keys(over).forEach(key => {
|
|
142
|
+
if (!over[key]) return; // no value to work with - skip it
|
|
143
|
+
// Look for something in the form of "thing-${VAR1}-${VAR2}-${VARn}-stuff"
|
|
144
|
+
|
|
145
|
+
const matches = over[key].match(/\$\{\w+\}/g);
|
|
146
|
+
if (!matches) return;
|
|
147
|
+
matches.forEach(replaceThis => {
|
|
148
|
+
// The matched variable names will be in the form of ${VARNAME} so drop
|
|
149
|
+
// the ${} characters before using the VARNAME to map into the
|
|
150
|
+
// overwhelm map containing the desired replacement value.
|
|
151
|
+
const withThat = over[replaceThis.replace(/\W+/g, '')];
|
|
152
|
+
|
|
153
|
+
if (!withThat) {
|
|
154
|
+
varErrors.push(`${key} : ${over[key]}`);
|
|
155
|
+
return;
|
|
156
|
+
} // Store the replaced string back in the overwhelm value map.
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
over[key] = over[key].replace(replaceThis, withThat);
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
if (varErrors.length > 0) {
|
|
164
|
+
console.log('***ERROR: unkown variable reference(s) in overwhelm.yaml:\n');
|
|
165
|
+
varErrors.forEach(error => {
|
|
166
|
+
console.log(` ${error}`);
|
|
167
|
+
});
|
|
168
|
+
console.log('');
|
|
169
|
+
process.exit(1);
|
|
170
|
+
} // Grab a list of the existing yaml templates.
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
const yams = glob.sync('values-*.yaml'); // A function to apply the replacements to all of the matching yaml which
|
|
174
|
+
// will error out if it runs into an unknown OVH<tag>.
|
|
175
|
+
|
|
176
|
+
const doReplacements = (yamls, replacements) => {
|
|
177
|
+
let replYaml = yamls;
|
|
178
|
+
Object.keys(replacements).forEach(repl => {
|
|
179
|
+
const replaceThis = new RegExp(`OVH:<${repl}>`, 'g');
|
|
180
|
+
const withThat = `${replacements[repl]}`;
|
|
181
|
+
replYaml = replYaml.replace(replaceThis, withThat);
|
|
182
|
+
}); // Verify all replaceables have been handled, or error out.
|
|
183
|
+
|
|
184
|
+
const missed = replYaml.match(/OVH:<(.*)>/g);
|
|
185
|
+
|
|
186
|
+
if (missed) {
|
|
187
|
+
console.log('\n***ERROR: missing replacements in overwhelm.yaml for these tags:\n');
|
|
188
|
+
missed.forEach(miss => {
|
|
189
|
+
console.log(` TAG: ${miss.match(/OVH:<(.*)>/)[1]}`);
|
|
190
|
+
});
|
|
191
|
+
console.log('');
|
|
192
|
+
process.exit(1);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
return replYaml;
|
|
196
|
+
}; // Collect all of the yaml from the yams, and always expect the default and
|
|
197
|
+
// platform yamls to be in that list.
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
const buildYaml = (yamls, replacements) => {
|
|
201
|
+
// We always start with default but values-platform is no longer needed.
|
|
202
|
+
const always = ['values-default.yaml'];
|
|
203
|
+
const values = [...always, ...yamls];
|
|
204
|
+
const loaded = [];
|
|
205
|
+
let allYamls = '';
|
|
206
|
+
values.forEach(yaml => {
|
|
207
|
+
if (!fs.existsSync(yaml)) {
|
|
208
|
+
console.log(`\n***ERROR: yaml file missing => ${yaml}\n`);
|
|
209
|
+
process.exit(1);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
if (!loaded.includes(yaml)) {
|
|
213
|
+
allYamls += `\n# AHOY => ${yaml}\n\n`;
|
|
214
|
+
allYamls += fs.readFileSync(yaml, {
|
|
215
|
+
encoding: 'utf-8'
|
|
216
|
+
});
|
|
217
|
+
loaded.push(yaml);
|
|
218
|
+
}
|
|
219
|
+
}); // Now apply all of the replacements from the overwhelm file.
|
|
220
|
+
|
|
221
|
+
return doReplacements(allYamls, replacements);
|
|
222
|
+
}; // Call buildYaml to replace the OVH strings in the yaml files.
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
const values = buildYaml(yams, over); // Check to see if someone is requesting a value from the yaml.
|
|
226
|
+
|
|
227
|
+
if (args.key) {
|
|
228
|
+
const section = args.section || 'default';
|
|
229
|
+
const keys = yaml[section];
|
|
230
|
+
|
|
231
|
+
if (args.verbose) {
|
|
232
|
+
console.log('replacements');
|
|
233
|
+
console.log(keys);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
if (args.export) {
|
|
237
|
+
console.log(`export ${args.key}=${keys[args.key]}`);
|
|
238
|
+
} else {
|
|
239
|
+
console.log(keys[args.key]);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
if (!args.continue) process.exit();
|
|
243
|
+
} // Find all of the potential target dirs. Utilize .gitignore to ignore files
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
const opt = {
|
|
247
|
+
ignore: parse(fs.readFileSync('.gitignore'))
|
|
248
|
+
};
|
|
249
|
+
const ahoy = glob.sync('*/', opt); // .noahoy = skips generation of values.yaml but allows helmup to run
|
|
250
|
+
// .nohelm = overwhelm and helmup will skip the deployment entirely
|
|
251
|
+
|
|
252
|
+
ahoy.forEach(dir => {
|
|
253
|
+
if (fs.existsSync(`${dir}/.noahoy`)) {
|
|
254
|
+
!args.fetchctx && console.log(chalk.yellow(`***WARNING: .noahoy detected, not regenerating ${dir}values.yaml`));
|
|
255
|
+
} else if (!fs.existsSync(`${dir}/.nohelm`)) {
|
|
256
|
+
args.verbose && console.log(`Generating values in ${dir}`); // eslint-disable-line no-unused-expressions
|
|
257
|
+
|
|
258
|
+
let valuesOut = []; // An accumulator for all of the output values.
|
|
259
|
+
// Add support for localized values for things like keel (or whatever)
|
|
260
|
+
|
|
261
|
+
const valuesLocal = `${dir}values-local.yaml`;
|
|
262
|
+
|
|
263
|
+
if (fs.existsSync(valuesLocal)) {
|
|
264
|
+
args.verbose && console.log(` Local values in ${valuesLocal}`); // eslint-disable-line no-unused-expressions
|
|
265
|
+
|
|
266
|
+
valuesOut += '\n# AHOY => values-local.yaml\n\n';
|
|
267
|
+
valuesOut += fs.readFileSync(valuesLocal, {
|
|
268
|
+
encoding: 'utf-8'
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
valuesOut += `\n${values}`;
|
|
273
|
+
valuesOut = doReplacements(valuesOut, over);
|
|
274
|
+
fs.writeFileSync(`${dir}/values.yaml`, valuesOut);
|
|
275
|
+
}
|
|
276
|
+
}); // Set the GCP context for safety!
|
|
277
|
+
|
|
278
|
+
const clusterName = over.CLUSTER_NAME;
|
|
279
|
+
const projectId = over.PROJECT_ID;
|
|
280
|
+
let zone = over['GCE_REGION'] + (over['GCE_ZONE'] ? `-${over['GCE_ZONE']}` : '');
|
|
281
|
+
|
|
282
|
+
if (!clusterName) {
|
|
283
|
+
console.log(chalk.yellow(`
|
|
284
|
+
|
|
285
|
+
The overwhelm.yaml file in this branch is missing a CLUSTER_NAME setting,
|
|
286
|
+
which was added to support cluster names that do not match the project
|
|
287
|
+
name. Since the mismatch is rare, you can probably get by with simply
|
|
288
|
+
adding this line following PROJECT_NAME in the default section of
|
|
289
|
+
overwhelm.yaml:
|
|
290
|
+
|
|
291
|
+
${chalk.bold.green(`CLUSTER_NAME : "\${PROJECT_NAME}"`)}
|
|
292
|
+
|
|
293
|
+
However, if the CLUSTER_NAME is not the same as the PROJECT_NAME then go
|
|
294
|
+
ahead and add the CLUSTER_NAME setting to the ${chalk.bold.green(projectId)} section of the
|
|
295
|
+
overwhelm.yaml file.
|
|
296
|
+
|
|
297
|
+
`));
|
|
298
|
+
process.exit(1);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
let kubeout = '_no_current_context_';
|
|
302
|
+
|
|
303
|
+
try {
|
|
304
|
+
kubeout = exec('kubectl config current-context', {
|
|
305
|
+
stdio: [undefined]
|
|
306
|
+
});
|
|
307
|
+
} catch (err) {// err && console.log( `Caught Error =>[${err}]` )
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
const currentCtx = kubeout.toString().trim();
|
|
311
|
+
let desiredCtx = `gke_${projectId}_${zone}_${clusterName}`;
|
|
312
|
+
let cmd = `gcloud container clusters get-credentials ${clusterName} --zone ${zone} --project ${projectId}`; // Check if we are using AWS
|
|
313
|
+
|
|
314
|
+
if (cfgs.CLOUD === 'aws') {
|
|
315
|
+
const awsAcctId = cfgs['AWS_ACCT_ID'];
|
|
316
|
+
zone = over['AWS_REGION'];
|
|
317
|
+
desiredCtx = `arn:aws:eks:${zone}:${awsAcctId}:cluster/${clusterName}`;
|
|
318
|
+
cmd = `aws eks --region ${zone} update-kubeconfig --name ${clusterName}`;
|
|
319
|
+
} // TODO - FETCH AWS CLUSTER CREDENTIALS
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
const matchedCtx = currentCtx === desiredCtx; // just fetch the context and exit if -f is specified
|
|
323
|
+
|
|
324
|
+
if (args.fetchctx) {
|
|
325
|
+
if (!matchedCtx) {
|
|
326
|
+
try {
|
|
327
|
+
exec(`${cmd}`, {
|
|
328
|
+
stdio: [undefined]
|
|
329
|
+
});
|
|
330
|
+
} catch (err) {
|
|
331
|
+
process.exit(61); // ECONNREFUSED
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
process.exit(0);
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
if (matchedCtx) {
|
|
339
|
+
console.log(`
|
|
340
|
+
|
|
341
|
+
Current context matches => ${chalk.bold.green(currentCtx)}
|
|
342
|
+
|
|
343
|
+
`);
|
|
344
|
+
} else {
|
|
345
|
+
console.log(`
|
|
346
|
+
You are about to change your Kubernetes context to:
|
|
347
|
+
CLUSTER_NAME => ${chalk.bold.green(clusterName)}
|
|
348
|
+
PROJECT_ID => ${chalk.bold.green(projectId)}
|
|
349
|
+
REGION => ${chalk.bold.green(zone)}
|
|
350
|
+
|
|
351
|
+
`);
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
const operation = matchedCtx ? 'refetch the credentials' : 'switch your context';
|
|
355
|
+
const ans = ask.question(`Enter "${chalk.bold.green('yes')}" if you wish to ${operation} => `);
|
|
356
|
+
|
|
357
|
+
if (ans !== 'yes') {
|
|
358
|
+
if (matchedCtx) {
|
|
359
|
+
console.log(chalk.bold.yellow('\n\nSkipping a refetch of your Kubernetes context and credentials\n\n'));
|
|
360
|
+
process.exit(0);
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
console.log(chalk.bold.red('\n\nYour Kubernetes context and credentials do NOT match - this could be bad!\n\n'));
|
|
364
|
+
process.exit(1);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
console.log(`\n\nExecuting: ${chalk.bold.yellow(cmd)}\n\n`);
|
|
368
|
+
exec(`${cmd}`, (error, out) => {
|
|
369
|
+
if (error) {
|
|
370
|
+
console.log(`\n\n***ERROR ${error}\n\n`);
|
|
371
|
+
process.exit(1);
|
|
372
|
+
}
|
|
373
|
+
});
|