@leverege/build-tools 2.2.2 → 2.2.3
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/CHANGELOG.md +4 -0
- package/lib/server/helmify/files.js +24 -0
- package/lib/server/helmify/helm.js +219 -0
- package/lib/server/helmify/index.js +46 -0
- package/package.json +12 -7
- package/src/helminit-dp +174 -0
- package/src/helminit-scaler +20 -0
- package/src/helminit-svc +21 -0
- package/src/helmup +1 -1
- package/lib/server/dnsify/CloudflareAPI.js +0 -103
- package/lib/server/dnsify/accounts.json.enc +0 -0
- package/lib/server/dnsify/index.js +0 -92
- package/lib/web/dnsify/CloudflareAPI.js +0 -256
- package/lib/web/dnsify/index.js +0 -153
- package/src/helmify +0 -266
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
All notable changes to this project will be documented in this file.
|
|
3
3
|
|
|
4
|
+
## [2.2.3] = 2020-04-22
|
|
5
|
+
### Updated
|
|
6
|
+
- (Helmify) Added a CLI interface for Helmup
|
|
7
|
+
|
|
4
8
|
## [2.1.5] - 2020-03-08
|
|
5
9
|
### Updated
|
|
6
10
|
- (Helmup) Simplified Timescale installation process
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
|
|
5
|
+
const path = require('path');
|
|
6
|
+
|
|
7
|
+
const inquirer = require('inquirer');
|
|
8
|
+
|
|
9
|
+
module.exports = {
|
|
10
|
+
getCurrentDirectoryBase: () => {
|
|
11
|
+
return path.basename(process.cwd());
|
|
12
|
+
},
|
|
13
|
+
directoryExists: filePath => {
|
|
14
|
+
return fs.existsSync(filePath);
|
|
15
|
+
},
|
|
16
|
+
overwriteDirectory: dirName => {
|
|
17
|
+
const question = [{
|
|
18
|
+
name: 'overwriteDirectory',
|
|
19
|
+
type: 'confirm',
|
|
20
|
+
message: `Overwrite existing ${dirName} directory?`
|
|
21
|
+
}];
|
|
22
|
+
return inquirer.prompt(question);
|
|
23
|
+
}
|
|
24
|
+
};
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
|
|
5
|
+
const fsp = fs.promises;
|
|
6
|
+
|
|
7
|
+
const path = require('path');
|
|
8
|
+
|
|
9
|
+
const inquirer = require('inquirer');
|
|
10
|
+
|
|
11
|
+
const chalk = require('chalk');
|
|
12
|
+
|
|
13
|
+
const execa = require('execa');
|
|
14
|
+
|
|
15
|
+
const yaml = require('js-yaml');
|
|
16
|
+
|
|
17
|
+
const packageJsonPath = path.join(process.cwd(), 'package.json');
|
|
18
|
+
|
|
19
|
+
const packageJson = require(`${packageJsonPath}`);
|
|
20
|
+
|
|
21
|
+
function sanitizePackageName(name) {
|
|
22
|
+
let validName = name; // Remove npm lib name (e.g. @leverege)
|
|
23
|
+
|
|
24
|
+
const isNpm = name.startsWith('@');
|
|
25
|
+
|
|
26
|
+
if (isNpm) {
|
|
27
|
+
const splitStr = name.split('/');
|
|
28
|
+
validName = splitStr[1]; // returns name after npm domain
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return validName;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function transformGoFormat(input) {
|
|
35
|
+
return input.replace(/-/g, '_');
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async function createChartYAML(chart) {
|
|
39
|
+
try {
|
|
40
|
+
await fsp.writeFile('helm/Chart.yaml', yaml.safeDump(chart), 'utf8');
|
|
41
|
+
} catch (err) {
|
|
42
|
+
console.error('Failed to create Chart.yaml file', chalk.red.bold('ERROR'));
|
|
43
|
+
process.exit(1);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async function createValuesYAML(name, version, redisAccess, securityContext, preemptible, service) {
|
|
48
|
+
const openPort = service !== 'none';
|
|
49
|
+
const portFromEnv = process.env.PORT || process.env.SERVER_PORT;
|
|
50
|
+
const portNumber = parseInt(portFromEnv) || 8080;
|
|
51
|
+
const values = {
|
|
52
|
+
[name]: {
|
|
53
|
+
"VERSION": version,
|
|
54
|
+
"PREMPTIBLE": preemptible,
|
|
55
|
+
...(openPort && {
|
|
56
|
+
port: portNumber
|
|
57
|
+
})
|
|
58
|
+
},
|
|
59
|
+
"redisClient": {
|
|
60
|
+
"label": redisAccess
|
|
61
|
+
},
|
|
62
|
+
"securityContext": {
|
|
63
|
+
"readOnlyRootFs": !securityContext
|
|
64
|
+
},
|
|
65
|
+
"cloud": {
|
|
66
|
+
"provider": "gcp",
|
|
67
|
+
"project": "",
|
|
68
|
+
"region": "",
|
|
69
|
+
"sqlInstance": ""
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
try {
|
|
74
|
+
await fsp.writeFile('helm/values.yaml', yaml.safeDump(values), 'utf8');
|
|
75
|
+
} catch (err) {
|
|
76
|
+
console.error('Failed to create values.yaml file', chalk.red.bold('ERROR'));
|
|
77
|
+
process.exit(1);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
async function createServiceYAML(name, serviceType) {
|
|
82
|
+
try {
|
|
83
|
+
await execa('helminit-svc', [name, serviceType]);
|
|
84
|
+
} catch (err) {
|
|
85
|
+
console.error('Failed to create service.yaml file', chalk.red.bold('ERROR'));
|
|
86
|
+
process.exit(1);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
async function createDeploymentYAML(name, enableFirebase, enableBigQuery) {
|
|
91
|
+
try {
|
|
92
|
+
await execa('helminit-dp', [name, enableFirebase, enableBigQuery]);
|
|
93
|
+
} catch (err) {
|
|
94
|
+
console.error('Failed to create deployment.yaml file', chalk.red.bold('ERROR'));
|
|
95
|
+
process.exit(1);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
async function createScalerYAML(name) {
|
|
100
|
+
try {
|
|
101
|
+
await execa('helminit-scaler', [name]);
|
|
102
|
+
} catch (err) {
|
|
103
|
+
console.error('Failed to create scaler.yaml file', chalk.red.bold('ERROR'));
|
|
104
|
+
process.exit(1);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
async function createTemplates() {
|
|
109
|
+
const helmQuestions = [{
|
|
110
|
+
name: 'redisAccess',
|
|
111
|
+
type: 'confirm',
|
|
112
|
+
message: 'Does this chart need access to Redis (e.g. cache, limit, lock options)?'
|
|
113
|
+
}, {
|
|
114
|
+
name: 'preemptible',
|
|
115
|
+
type: 'confirm',
|
|
116
|
+
message: 'Is this server stateless and can survive occasional unavailability?'
|
|
117
|
+
}, {
|
|
118
|
+
name: 'securityContext',
|
|
119
|
+
type: 'confirm',
|
|
120
|
+
message: 'Does this server need special write access to filesystem?'
|
|
121
|
+
}, {
|
|
122
|
+
name: 'service',
|
|
123
|
+
type: 'rawlist',
|
|
124
|
+
message: 'Does this server need a TCP port open for internal or external access?',
|
|
125
|
+
choices: ['none', 'internal', 'external'],
|
|
126
|
+
default: ['none']
|
|
127
|
+
}, {
|
|
128
|
+
name: 'scaler',
|
|
129
|
+
type: 'confirm',
|
|
130
|
+
message: 'Does this server need horizontal scaling?'
|
|
131
|
+
}, {
|
|
132
|
+
name: 'cloud',
|
|
133
|
+
type: 'rawlist',
|
|
134
|
+
message: 'By default, which cloud platform will this server be deployed on?',
|
|
135
|
+
choices: ['GCP', 'AWS'],
|
|
136
|
+
default: ['GCP']
|
|
137
|
+
}, {
|
|
138
|
+
name: 'cloudServices',
|
|
139
|
+
type: 'checkbox',
|
|
140
|
+
message: 'Which these cloud services does this server need? (space to choose, enter to submit)',
|
|
141
|
+
choices: ['firebase', 'bigquery']
|
|
142
|
+
}];
|
|
143
|
+
const helmOptions = await inquirer.prompt(helmQuestions);
|
|
144
|
+
return helmOptions;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
module.exports = {
|
|
148
|
+
bootstrap: async () => {
|
|
149
|
+
let name = sanitizePackageName(packageJson.name);
|
|
150
|
+
const appVersion = packageJson.version;
|
|
151
|
+
const keepNameQuestion = [{
|
|
152
|
+
name: 'keepPackageName',
|
|
153
|
+
type: 'confirm',
|
|
154
|
+
message: `Helm chart name will default to ${name}. Do you want to keep the default setting?`
|
|
155
|
+
}];
|
|
156
|
+
const keepName = await inquirer.prompt(keepNameQuestion);
|
|
157
|
+
|
|
158
|
+
if (!keepName.keepPackageName) {
|
|
159
|
+
const keepNameQuestion = [{
|
|
160
|
+
name: 'renamePackage',
|
|
161
|
+
type: 'input',
|
|
162
|
+
message: 'Please enter a new name for the Helm chart',
|
|
163
|
+
validate: str => {
|
|
164
|
+
const helmRegex = RegExp('^(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])+$');
|
|
165
|
+
|
|
166
|
+
if (helmRegex.test(str)) {
|
|
167
|
+
return true;
|
|
168
|
+
} else {
|
|
169
|
+
return 'Special characters are not allowed. Please enter a valid name.';
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}];
|
|
173
|
+
const newName = await inquirer.prompt(keepNameQuestion);
|
|
174
|
+
name = newName.renamePackage;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
console.log(chalk.green(`\nBootstrapping a new Helm chart for ${name}...\n`));
|
|
178
|
+
const chart = {
|
|
179
|
+
name,
|
|
180
|
+
version: "1.0.0",
|
|
181
|
+
appVersion
|
|
182
|
+
};
|
|
183
|
+
const chartSafeName = transformGoFormat(name);
|
|
184
|
+
|
|
185
|
+
try {
|
|
186
|
+
await execa('mkdir', ['helm']);
|
|
187
|
+
await execa('mkdir', ['helm/templates']);
|
|
188
|
+
} catch (err) {
|
|
189
|
+
console.error('Failed to create directories', chalk.red.bold('ERROR'));
|
|
190
|
+
process.exit(1);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
const templateOpts = await createTemplates();
|
|
194
|
+
const {
|
|
195
|
+
service,
|
|
196
|
+
scaler,
|
|
197
|
+
cloudServices,
|
|
198
|
+
redisAccess,
|
|
199
|
+
securityContext,
|
|
200
|
+
preemptible
|
|
201
|
+
} = templateOpts;
|
|
202
|
+
|
|
203
|
+
if (service !== 'none') {
|
|
204
|
+
const serviceType = service === 'internal' ? 'ClusterIP' : 'NodePort';
|
|
205
|
+
await createServiceYAML(chartSafeName, serviceType);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
if (scaler) {
|
|
209
|
+
await createScalerYAML(chartSafeName);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
const enableFirebase = cloudServices.includes('firebase');
|
|
213
|
+
const enableBigQuery = cloudServices.includes('bigquery');
|
|
214
|
+
await createDeploymentYAML(name, enableFirebase, enableBigQuery);
|
|
215
|
+
await createValuesYAML(chartSafeName, appVersion, redisAccess, securityContext, preemptible, service);
|
|
216
|
+
console.log(chalk.green.bold(`\n\n Helm chart for ${name} is now ready \n`));
|
|
217
|
+
console.log(chalk.yellow.bold('Add any additional env vars to value.yaml and deployment.yaml prior to deployment'));
|
|
218
|
+
}
|
|
219
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
|
|
4
|
+
require('dotenv').config(); // attempt to autodetect envs
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
const chalk = require('chalk');
|
|
8
|
+
|
|
9
|
+
const clear = require('clear');
|
|
10
|
+
|
|
11
|
+
const figlet = require('figlet');
|
|
12
|
+
|
|
13
|
+
const execa = require('execa');
|
|
14
|
+
|
|
15
|
+
const files = require('./files');
|
|
16
|
+
|
|
17
|
+
const helm = require('./helm');
|
|
18
|
+
|
|
19
|
+
clear();
|
|
20
|
+
console.log(chalk.yellow(figlet.textSync('Helmify', {
|
|
21
|
+
horizontalLayout: 'full'
|
|
22
|
+
})));
|
|
23
|
+
|
|
24
|
+
const run = async () => {
|
|
25
|
+
if (files.directoryExists('helm')) {
|
|
26
|
+
console.log(chalk.red.bold('\nDetected existing Helm configs\n'));
|
|
27
|
+
const overwrite = await files.overwriteDirectory('Helm');
|
|
28
|
+
|
|
29
|
+
if (!overwrite.overwriteDirectory) {
|
|
30
|
+
console.log(chalk.green('\nNo changes made - exiting... \n'));
|
|
31
|
+
process.exit();
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
console.log(chalk.yellow.bold('\nDeleting existing Helm directory...\n'));
|
|
35
|
+
const deleteHelmDir = await execa('rm', ['-rf', 'helm']);
|
|
36
|
+
|
|
37
|
+
if (deleteHelmDir.failed) {
|
|
38
|
+
console.log(chalk.red.bold('\nFailed to delete existing Helm directory\n'));
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
helm.bootstrap();
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
run();
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@leverege/build-tools",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.3",
|
|
4
4
|
"description": "A collection of build / support tools for Leverege developers",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"build": "npm run compile",
|
|
8
8
|
"compile": "rm -fr lib && npm run compile_server && npm run compile_web",
|
|
9
|
-
"compile_server": "NODE_ENV=server babel -d lib/server src/
|
|
9
|
+
"compile_server": "NODE_ENV=server babel -d lib/server src/",
|
|
10
10
|
"compile_web": "NODE_ENV=web babel -d lib/web src/",
|
|
11
11
|
"licenseCheck": "license-checker --summary --failOn GPL",
|
|
12
12
|
"prepublintOnly": "npm run lint && npm run build",
|
|
@@ -17,14 +17,16 @@
|
|
|
17
17
|
"circleate": "src/circleate",
|
|
18
18
|
"decrypt-secrets": "src/decrypt-secrets",
|
|
19
19
|
"dirty-git": "src/dirty-git",
|
|
20
|
-
"dnsify": "lib/server/dnsify/index.js",
|
|
21
20
|
"dockreate": "src/dockreate",
|
|
22
21
|
"encrypt-secrets": "src/encrypt-secrets",
|
|
23
22
|
"getfbcfg": "src/getfbcfg",
|
|
24
23
|
"getjson": "src/getjson",
|
|
25
24
|
"git-tar": "src/git-tar",
|
|
26
25
|
"helmdn": "src/helmdn",
|
|
27
|
-
"helmify": "
|
|
26
|
+
"helmify": "lib/server/helmify/index.js",
|
|
27
|
+
"helminit-svc": "src/helminit-svc",
|
|
28
|
+
"helminit-dp": "src/helminit-dp",
|
|
29
|
+
"helminit-scaler": "src/helminit-scaler",
|
|
28
30
|
"helmup": "src/helmup",
|
|
29
31
|
"k8x": "src/k8x",
|
|
30
32
|
"overwhelm": "src/overwhelm",
|
|
@@ -40,14 +42,17 @@
|
|
|
40
42
|
"@google-cloud/kms": "^1.6.3",
|
|
41
43
|
"async": "^3.2.0",
|
|
42
44
|
"chalk": "^3.0.0",
|
|
43
|
-
"
|
|
44
|
-
"command-line-args": "^5.1.1",
|
|
45
|
-
"command-line-usage": "^5.0.5",
|
|
45
|
+
"clear": "^0.1.0",
|
|
46
46
|
"commander": "^2.20.3",
|
|
47
|
+
"dotenv": "^8.2.0",
|
|
48
|
+
"execa": "^4.0.0",
|
|
49
|
+
"figlet": "^1.3.0",
|
|
47
50
|
"fs-extra": "^8.1.0",
|
|
48
51
|
"git-branch": "^2.0.1",
|
|
49
52
|
"glob": "^7.1.6",
|
|
53
|
+
"inquirer": "^7.1.0",
|
|
50
54
|
"js-yaml": "^3.13.1",
|
|
55
|
+
"minimist": "^1.2.5",
|
|
51
56
|
"ora": "^3.4.0",
|
|
52
57
|
"parse-gitignore": "^1.0.1",
|
|
53
58
|
"readline-sync": "^1.4.10",
|
package/src/helminit-dp
ADDED
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
dockerName=$1
|
|
4
|
+
chartName=${dockerName//-/_}
|
|
5
|
+
|
|
6
|
+
enableFirebase=$2
|
|
7
|
+
enableBigQuery=$3
|
|
8
|
+
|
|
9
|
+
if [ "$enableFirebase" = true ] ; then
|
|
10
|
+
firebaseVolume="
|
|
11
|
+
- name: rt-firebase-key
|
|
12
|
+
secret:
|
|
13
|
+
secretName: rt-data
|
|
14
|
+
- name: model-firebase-key
|
|
15
|
+
secret:
|
|
16
|
+
secretName: model-data
|
|
17
|
+
- name: model-firebase-config
|
|
18
|
+
secret:
|
|
19
|
+
secretName: model-data-config
|
|
20
|
+
- name: rt-firebase-config
|
|
21
|
+
secret:
|
|
22
|
+
secretName: rt-data-config"
|
|
23
|
+
|
|
24
|
+
firebaseVolumeMount='
|
|
25
|
+
- name: model-firebase-key
|
|
26
|
+
mountPath: "/home/node/.gcp/model-data"
|
|
27
|
+
- name: rt-firebase-key
|
|
28
|
+
mountPath: "/home/node/.gcp/rt-data"
|
|
29
|
+
- name: model-firebase-config
|
|
30
|
+
mountPath: "/home/node/.gcp/model-data-config"
|
|
31
|
+
- name: rt-firebase-config
|
|
32
|
+
mountPath: "/home/node/.gcp/rt-data-config"'
|
|
33
|
+
fi
|
|
34
|
+
|
|
35
|
+
if [ "$enableBigQuery" = true ] ; then
|
|
36
|
+
bigQueryVolume="
|
|
37
|
+
- name: big-query
|
|
38
|
+
secret:
|
|
39
|
+
secretName: big-query"
|
|
40
|
+
|
|
41
|
+
bigQueryVolumeMount='
|
|
42
|
+
- name: big-query
|
|
43
|
+
mountPath: "/home/node/.gcp/bigquery"'
|
|
44
|
+
fi
|
|
45
|
+
|
|
46
|
+
touch helm/templates/deployment.yaml
|
|
47
|
+
|
|
48
|
+
cat<<EODEPLOYMENT > helm/templates/deployment.yaml
|
|
49
|
+
{{- if .Values.cloud.provider -}}
|
|
50
|
+
{{- \$provider := .Values.cloud.provider -}}
|
|
51
|
+
apiVersion: apps/v1
|
|
52
|
+
kind: Deployment
|
|
53
|
+
metadata:
|
|
54
|
+
name: {{ .Chart.Name }}
|
|
55
|
+
labels:
|
|
56
|
+
app: {{ .Chart.Name }}
|
|
57
|
+
chart/version: {{ .Chart.Version }}
|
|
58
|
+
chart/appVersion: {{ .Chart.AppVersion }}
|
|
59
|
+
redis-client: {{ .Values.redisClient.label | quote }}
|
|
60
|
+
spec:
|
|
61
|
+
selector:
|
|
62
|
+
matchLabels:
|
|
63
|
+
app: {{ .Chart.Name }}
|
|
64
|
+
template:
|
|
65
|
+
metadata:
|
|
66
|
+
labels:
|
|
67
|
+
app: {{ .Chart.Name }}
|
|
68
|
+
chart/version: {{ .Chart.Version }}
|
|
69
|
+
chart/appVersion: {{ .Chart.AppVersion }}
|
|
70
|
+
redis-client: {{ .Values.redisClient.label | quote }}
|
|
71
|
+
annotations:
|
|
72
|
+
prometheus.io/port: '5111'
|
|
73
|
+
prometheus.io/scrape: 'true'
|
|
74
|
+
configmap.reloader.stakater.com/reload: "default-configs"
|
|
75
|
+
spec:
|
|
76
|
+
volumes: $firebaseVolume $bigQueryVolume
|
|
77
|
+
{{- if eq \$provider "gcp" }}
|
|
78
|
+
- name: pubsub-key
|
|
79
|
+
secret:
|
|
80
|
+
secretName: pubsub
|
|
81
|
+
{{- else if eq \$provider "aws" }}
|
|
82
|
+
- name: sns-sqs-key
|
|
83
|
+
secret:
|
|
84
|
+
secretName: sns-sqs
|
|
85
|
+
{{- end }}
|
|
86
|
+
- name: tmpfs
|
|
87
|
+
emptyDir: {}
|
|
88
|
+
{{- if .Values.$chartName.PREEMPTIBLE }}
|
|
89
|
+
tolerations:
|
|
90
|
+
- key: "preemptible"
|
|
91
|
+
operator: "Equal"
|
|
92
|
+
value: "true"
|
|
93
|
+
effect: "NoSchedule"
|
|
94
|
+
affinity:
|
|
95
|
+
nodeAffinity:
|
|
96
|
+
preferredDuringSchedulingIgnoredDuringExecution:
|
|
97
|
+
- preference:
|
|
98
|
+
matchExpressions:
|
|
99
|
+
- key: cloud.google.com/gke-preemptible
|
|
100
|
+
operator: Exists
|
|
101
|
+
weight: 100
|
|
102
|
+
{{- end }}
|
|
103
|
+
containers:
|
|
104
|
+
- name: {{ .Chart.Name }}
|
|
105
|
+
imagePullPolicy: Always
|
|
106
|
+
image: gcr.io/leverege-docker-images/$dockerName:{{ .Values.$chartName.VERSION }}
|
|
107
|
+
securityContext:
|
|
108
|
+
readOnlyRootFilesystem: {{ .Values.securityContext.readOnlyRootFs }}
|
|
109
|
+
runAsNonRoot: true
|
|
110
|
+
runAsUser: 1000
|
|
111
|
+
allowPrivilegeEscalation: false
|
|
112
|
+
# UNCOMMENT IF YOU NEED PROBES
|
|
113
|
+
# readinessProbe:
|
|
114
|
+
# httpGet:
|
|
115
|
+
# path: /healthz
|
|
116
|
+
# port: api
|
|
117
|
+
# initialDelaySeconds: 10
|
|
118
|
+
# livenessProbe:
|
|
119
|
+
# httpGet:
|
|
120
|
+
# path: /livenessProbe
|
|
121
|
+
# port: api
|
|
122
|
+
# initialDelaySeconds: 15
|
|
123
|
+
# periodSeconds: 60
|
|
124
|
+
ports:
|
|
125
|
+
{{- if .Values.$chartName.port }}
|
|
126
|
+
- name: api
|
|
127
|
+
containerPort: {{ .Values.$chartName.port }}
|
|
128
|
+
{{- end }}
|
|
129
|
+
- name: node-metrics
|
|
130
|
+
containerPort: 5111
|
|
131
|
+
resources:
|
|
132
|
+
requests:
|
|
133
|
+
cpu: "50m"
|
|
134
|
+
memory: "128Mi"
|
|
135
|
+
limits:
|
|
136
|
+
cpu: "100m"
|
|
137
|
+
memory: "256Mi"
|
|
138
|
+
volumeMounts: $firebaseVolumeMount $bigQueryVolumeMount
|
|
139
|
+
{{- if eq \$provider "gcp" }}
|
|
140
|
+
- name: pubsub-key
|
|
141
|
+
mountPath: "/home/node/.gcp/pubsub"
|
|
142
|
+
{{- else if eq \$provider "aws" }}
|
|
143
|
+
- name: sns-sqs-key
|
|
144
|
+
mountPath: "/home/node/.aws"
|
|
145
|
+
{{- end }}
|
|
146
|
+
- name: tmpfs
|
|
147
|
+
mountPath: "/tmp"
|
|
148
|
+
envFrom:
|
|
149
|
+
- configMapRef:
|
|
150
|
+
name: default-configs
|
|
151
|
+
env:
|
|
152
|
+
# UNCOMMENT THE FOLLOWING FOR ENV VARIABLES
|
|
153
|
+
# Assuming you have the following lines in values.yaml =>
|
|
154
|
+
#
|
|
155
|
+
# $chartName:
|
|
156
|
+
# MY_ENV_VARIABLE: hello-world
|
|
157
|
+
#
|
|
158
|
+
#
|
|
159
|
+
# - name: MY_ENV_VARIABLE
|
|
160
|
+
# value: {{ .Values.$chartName.MY_ENV_VARIABLE }}
|
|
161
|
+
#
|
|
162
|
+
#
|
|
163
|
+
# UNCOMMENT THE FOLLOWING FOR MOUNTING SECRETS
|
|
164
|
+
# Assuming you ran =>
|
|
165
|
+
# kubectl create secret generic my-secret --from-literal=my-password=password123
|
|
166
|
+
#
|
|
167
|
+
# - name: ENV_SECRET_NAME
|
|
168
|
+
# valueFrom:
|
|
169
|
+
# secretKeyRef:
|
|
170
|
+
# name: my-secret
|
|
171
|
+
# key: my-password
|
|
172
|
+
|
|
173
|
+
{{- end -}}
|
|
174
|
+
EODEPLOYMENT
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
chartName=$1
|
|
4
|
+
|
|
5
|
+
touch helm/templates/scaler.yaml
|
|
6
|
+
|
|
7
|
+
cat<<EOSCALER > helm/templates/scaler.yaml
|
|
8
|
+
apiVersion: autoscaling/v1
|
|
9
|
+
kind: HorizontalPodAutoscaler
|
|
10
|
+
metadata:
|
|
11
|
+
name: {{ .Chart.Name }}
|
|
12
|
+
spec:
|
|
13
|
+
scaleTargetRef:
|
|
14
|
+
apiVersion: apps/v1
|
|
15
|
+
kind: Deployment
|
|
16
|
+
name: {{ .Chart.Name }}
|
|
17
|
+
minReplicas: {{ .Values.horizontalScaler.minReplicas }}
|
|
18
|
+
maxReplicas: {{ .Values.horizontalScaler.maxReplicas }}
|
|
19
|
+
targetCPUUtilizationPercentage: {{ .Values.horizontalScaler.maxCPU }}
|
|
20
|
+
EOSCALER
|
package/src/helminit-svc
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
chartName=$1
|
|
4
|
+
serviceType=$2
|
|
5
|
+
|
|
6
|
+
touch helm/templates/service.yaml
|
|
7
|
+
|
|
8
|
+
cat<<EOSERVICE > helm/templates/service.yaml
|
|
9
|
+
kind: Service
|
|
10
|
+
apiVersion: v1
|
|
11
|
+
metadata:
|
|
12
|
+
name: {{ .Chart.Name }}
|
|
13
|
+
spec:
|
|
14
|
+
type: $serviceType
|
|
15
|
+
selector:
|
|
16
|
+
app: {{ .Chart.Name }}
|
|
17
|
+
ports:
|
|
18
|
+
- protocol: TCP
|
|
19
|
+
port: {{ .Values.$chartName.serverPort }}
|
|
20
|
+
targetPort: api
|
|
21
|
+
EOSERVICE
|
package/src/helmup
CHANGED
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
const ora = require('ora');
|
|
4
|
-
|
|
5
|
-
const fs = require('fs');
|
|
6
|
-
|
|
7
|
-
const path = require('path');
|
|
8
|
-
|
|
9
|
-
const {
|
|
10
|
-
promisify
|
|
11
|
-
} = require('util');
|
|
12
|
-
|
|
13
|
-
class CloudflareAPI {
|
|
14
|
-
constructor(options) {
|
|
15
|
-
const {
|
|
16
|
-
args
|
|
17
|
-
} = options;
|
|
18
|
-
const {
|
|
19
|
-
url,
|
|
20
|
-
proxy,
|
|
21
|
-
ipaddress,
|
|
22
|
-
account
|
|
23
|
-
} = args;
|
|
24
|
-
this.url = url;
|
|
25
|
-
this.proxy = proxy;
|
|
26
|
-
this.ipaddress = ipaddress;
|
|
27
|
-
this.spinner = ora({
|
|
28
|
-
text: 'Creating DNS record...',
|
|
29
|
-
spinner: 'monkey'
|
|
30
|
-
});
|
|
31
|
-
this.account = account;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
async decrypt(projectId = 'leverege-docker-images', keyRingId = 'build-tools', cryptoKeyId = 'circle-ci', ciphertextFileName = './accounts.json.enc', plaintextFileName = './accounts.json') {
|
|
35
|
-
// Import the library and create a client
|
|
36
|
-
const kms = require('@google-cloud/kms');
|
|
37
|
-
|
|
38
|
-
const client = new kms.KeyManagementServiceClient(); // The location of the crypto key's key ring, e.g. "global"
|
|
39
|
-
|
|
40
|
-
const locationId = 'us-east4'; // Reads the file to be decrypted
|
|
41
|
-
|
|
42
|
-
const readFile = promisify(fs.readFile);
|
|
43
|
-
const contentsBuffer = await readFile(path.resolve(__dirname, ciphertextFileName));
|
|
44
|
-
const name = client.cryptoKeyPath(projectId, locationId, keyRingId, cryptoKeyId);
|
|
45
|
-
const ciphertext = contentsBuffer.toString('base64'); // Decrypts the file using the specified crypto key
|
|
46
|
-
|
|
47
|
-
const [result] = await client.decrypt({
|
|
48
|
-
name,
|
|
49
|
-
ciphertext
|
|
50
|
-
}); // Writes the decrypted file to disk
|
|
51
|
-
|
|
52
|
-
const writeFile = promisify(fs.writeFile);
|
|
53
|
-
await writeFile(path.resolve(__dirname, plaintextFileName), Buffer.from(result.plaintext, 'base64'));
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
setAccountValues() {
|
|
57
|
-
const accountJson = require(path.resolve(__dirname, './accounts.json'));
|
|
58
|
-
|
|
59
|
-
const accountInfo = accountJson[this.account];
|
|
60
|
-
const {
|
|
61
|
-
email,
|
|
62
|
-
key,
|
|
63
|
-
zone
|
|
64
|
-
} = accountInfo;
|
|
65
|
-
this.cf = require('cloudflare')({
|
|
66
|
-
email,
|
|
67
|
-
key
|
|
68
|
-
});
|
|
69
|
-
this.zone = zone;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
async deleteSecrets() {
|
|
73
|
-
const deleteFile = promisify(fs.unlink);
|
|
74
|
-
await deleteFile(path.resolve(__dirname, './accounts.json'));
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
async createDNSRecord() {
|
|
78
|
-
try {
|
|
79
|
-
this.spinner.start();
|
|
80
|
-
this.spinner.text = 'Decrypting Cloudflare secrets...';
|
|
81
|
-
await this.decrypt();
|
|
82
|
-
this.spinner.text = 'Initializing Cloudflare API...';
|
|
83
|
-
this.setAccountValues();
|
|
84
|
-
this.spinner.text = 'Adding A name record...';
|
|
85
|
-
await this.cf.dnsRecords.add(this.zone, {
|
|
86
|
-
type: 'A',
|
|
87
|
-
name: this.url,
|
|
88
|
-
content: this.ipaddress,
|
|
89
|
-
proxied: this.proxy
|
|
90
|
-
});
|
|
91
|
-
this.spinner.text = 'Removing secrets...';
|
|
92
|
-
await this.deleteSecrets();
|
|
93
|
-
this.spinner.stop();
|
|
94
|
-
} catch (ex) {
|
|
95
|
-
this.spinner.stop();
|
|
96
|
-
console.log(ex);
|
|
97
|
-
throw ex;
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
module.exports = CloudflareAPI;
|
|
Binary file
|