@leverege/build-tools 2.94.0 → 2.95.0
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/.vscode/launch.json +14 -0
- package/package.json +5 -2
- package/src/Docker.mjs +3 -2
- package/src/Utils.mjs +53 -6
- package/src/artifacts/Utils.mjs +1 -1
- package/src/bash-funcs +1 -1
- package/src/git-tar.sh +1 -1
- package/src/helm-charts/emailer/values-local.yaml +1 -8
- package/src/helm-charts/prom-operator/helmup.plugin +1 -1
- package/src/helm-charts/traefik/helmup.plugin +1 -1
- package/src/helm-charts/velero/README.md +135 -0
- package/src/helm-charts/velero/helmup.bootstrap +1 -0
- package/src/helm-charts/velero/helmup.plugin +29 -2
- package/src/helm-charts/velero/values-local.yaml +1 -1
- package/src/helmup.sh +49 -41
- package/src/service-man/ServiceMan.mjs +75 -0
- package/src/service-man/config/CommandLine.mjs +199 -0
- package/src/service-man/config/Config.mjs +203 -0
- package/src/service-man/config/VersionCheck.mjs +79 -0
- package/src/service-man/config/iam-roles/leveregeBigQueryReader.json +10 -0
- package/src/service-man/config/iam-roles/leveregeBigQueryWriter.json +13 -0
- package/src/service-man/config/iam-roles/leveregeCloudFunctionsManager.json +12 -0
- package/src/service-man/config/iam-roles/leveregeFirebaseHosting.json +9 -0
- package/src/service-man/config/iam-roles/leveregeFirebaseMessaging.json +13 -0
- package/src/service-man/config/iam-roles/leveregeFirebaseUpdates.json +10 -0
- package/src/service-man/config/iam-roles/leveregeLogsViewer.json +8 -0
- package/src/service-man/config/iam-roles/leveregePubSub.json +13 -0
- package/src/service-man/config/iam-roles/leveregeSecretsViewer.json +9 -0
- package/src/service-man/config/iam-roles/leveregeStorageObjectAdmin.json +21 -0
- package/src/service-man/config/iam-roles/leveregeStorageObjectReader.json +13 -0
- package/src/service-man/config/iam-roles/leveregeSvcAcctActor.json +8 -0
- package/src/service-man/config/iam-roles/leveregeSvcAcctTokenCreator.json +8 -0
- package/src/service-man/config/index.mjs +7 -0
- package/src/service-man/config/secrets/authz-jwt.json +6 -0
- package/src/service-man/config/secrets/authz-postgres.json +7 -0
- package/src/service-man/config/secrets/db-timescale-dense.json +8 -0
- package/src/service-man/config/secrets/jwt-options.json +7 -0
- package/src/service-man/config/secrets/mail-gun-api-key.json +6 -0
- package/src/service-man/config/secrets/npmrc.json +6 -0
- package/src/service-man/config/secrets/oidc-client-secret.json +6 -0
- package/src/service-man/config/secrets/postgresql-password.json +8 -0
- package/src/service-man/config/secrets/session-secret.json +6 -0
- package/src/service-man/config/secrets/twilio.json +8 -0
- package/src/service-man/config/service-accounts/api-server.json +12 -0
- package/src/service-man/config/service-accounts/authz-server.json +5 -0
- package/src/service-man/config/service-accounts/db-curator.json +8 -0
- package/src/service-man/config/service-accounts/emailer.json +7 -0
- package/src/service-man/config/service-accounts/fota-server.json +6 -0
- package/src/service-man/config/service-accounts/geotile-server.json +8 -0
- package/src/service-man/config/service-accounts/imagine.json +6 -0
- package/src/service-man/config/service-accounts/message-processor.json +6 -0
- package/src/service-man/config/service-accounts/messenger.json +7 -0
- package/src/service-man/config/service-accounts/pubsub-pulse.json +6 -0
- package/src/service-man/config/service-accounts/push-notifier.json +8 -0
- package/src/service-man/config/service-accounts/reason.json +5 -0
- package/src/service-man/config/service-accounts/resource-server.json +9 -0
- package/src/service-man/config/service-accounts/rule-engine.json +7 -0
- package/src/service-man/config/service-accounts/scheduler.json +6 -0
- package/src/service-man/config/service-accounts/transponder.json +15 -0
- package/src/service-man/gcloud-k8s/RolesManager.mjs +41 -0
- package/src/service-man/gcloud-k8s/SecretsManager.mjs +182 -0
- package/src/service-man/gcloud-k8s/ServiceAccountManager.mjs +246 -0
- package/src/service-man/gcloud-k8s/VersionManager.mjs +114 -0
- package/src/service-man/gcloud-k8s/index.mjs +11 -0
- package/src/service-man/service-man.mjs +18 -0
- package/src/service-man/utils/index.mjs +83 -0
- package/leverege-build-tools-2.21.13.tgz +0 -0
- package/lib/server/build-tools.js +0 -138
- package/lib/server/firebaseDeploy.js +0 -195
- package/lib/server/firebaseServe.js +0 -116
- package/lib/server/getfbcfg.js +0 -25
- package/lib/server/getjson.js +0 -70
- package/lib/server/overwhelm.js +0 -447
- package/lib/server/push-my-chart.js +0 -18
- package/lib/server/refresh-npm-token.js +0 -135
- package/lib/server/tag-release.js +0 -681
- package/lib/server/unleash.js +0 -50
- package/lib/web/build-tools.js +0 -138
- package/lib/web/firebaseDeploy.js +0 -195
- package/lib/web/firebaseServe.js +0 -116
- package/lib/web/getfbcfg.js +0 -25
- package/lib/web/getjson.js +0 -70
- package/lib/web/overwhelm.js +0 -447
- package/lib/web/push-my-chart.js +0 -18
- package/lib/web/refresh-npm-token.js +0 -135
- package/lib/web/tag-release.js +0 -681
- package/lib/web/unleash.js +0 -50
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import fs from 'node:fs'
|
|
2
|
+
|
|
3
|
+
import chalk from 'chalk'
|
|
4
|
+
import commandLineArgs from 'command-line-args'
|
|
5
|
+
import commandLineUsage from 'command-line-usage'
|
|
6
|
+
import inquirer from 'inquirer'
|
|
7
|
+
|
|
8
|
+
import { log, } from '../../Utils.mjs'
|
|
9
|
+
|
|
10
|
+
import VersionCheck from './VersionCheck.mjs'
|
|
11
|
+
|
|
12
|
+
const cliOptionList = [ // Use cliOptionList to tie into the Usage statements
|
|
13
|
+
{
|
|
14
|
+
name : 'fetch-versions',
|
|
15
|
+
type : Boolean,
|
|
16
|
+
default : false,
|
|
17
|
+
description : '{green create Versions.json from current k8s context}',
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
name : 'create-service',
|
|
21
|
+
type : String,
|
|
22
|
+
default : false,
|
|
23
|
+
description : '{green create a new service account and bind workload identity}',
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
name : 'create-sa',
|
|
27
|
+
type : String,
|
|
28
|
+
default : false,
|
|
29
|
+
description : '{green create a new service account without binding}',
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
name : 'namespace',
|
|
33
|
+
type : String,
|
|
34
|
+
default : 'default',
|
|
35
|
+
description : '{green the namespace to use if it is other than default}',
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
name : 'dump-configs',
|
|
39
|
+
type : String,
|
|
40
|
+
default : false,
|
|
41
|
+
description : '{green dumps the service-man configs to the specified directory}',
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
name : 'use-configs',
|
|
45
|
+
type : String,
|
|
46
|
+
default : false,
|
|
47
|
+
description : '{green overrides where service-man gets its configs}',
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
name : 'setup-secrets',
|
|
51
|
+
type : Boolean,
|
|
52
|
+
default : false,
|
|
53
|
+
description : '{red [re]generates the standard random secrets}',
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
name : 'setup-roles',
|
|
57
|
+
type : Boolean,
|
|
58
|
+
default : false,
|
|
59
|
+
description : '{yellow define the Leverege IAM roles}',
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
name : 'setup-services',
|
|
63
|
+
type : String,
|
|
64
|
+
default : false,
|
|
65
|
+
description : '{yellow create the platform Leverege Svc Accts}',
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
name : 'setup-services-dir',
|
|
69
|
+
type : String,
|
|
70
|
+
default : undefined,
|
|
71
|
+
description : '{yellow specify the Svc Accts directory}',
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
name : 'new-k8s',
|
|
75
|
+
type : Boolean,
|
|
76
|
+
default : false,
|
|
77
|
+
description : '{yellow shortcut for --setup-secrets --setup-roles --setup-services}',
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
name : 'sync-secrets',
|
|
81
|
+
type : String,
|
|
82
|
+
default : false,
|
|
83
|
+
description : '{yellow synchronize secret mgr secret to k8s secret <mgr_sec>=<k8s_sec>}',
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
name : 'from-helmup',
|
|
87
|
+
type : Boolean,
|
|
88
|
+
default : false,
|
|
89
|
+
description : '{red was invoked from helmup - cuts down on double k8s context set}',
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
name : 'help',
|
|
93
|
+
type : Boolean,
|
|
94
|
+
default : false,
|
|
95
|
+
description : '{green display this help screen}',
|
|
96
|
+
},
|
|
97
|
+
{ name : 'version',
|
|
98
|
+
type : Boolean,
|
|
99
|
+
default : false,
|
|
100
|
+
description : '{green returns the build-tools repo version}',
|
|
101
|
+
},
|
|
102
|
+
{ name : 'verbose',
|
|
103
|
+
alias : 'v',
|
|
104
|
+
type : Boolean,
|
|
105
|
+
default : false,
|
|
106
|
+
description : '{green emit additional info at run time}',
|
|
107
|
+
},
|
|
108
|
+
]
|
|
109
|
+
|
|
110
|
+
const sections = [
|
|
111
|
+
{
|
|
112
|
+
header : 'Leverege Service Management Tool',
|
|
113
|
+
content : `
|
|
114
|
+
{green This utility attempts to ease the pain of managing IAM roles and the creation of service accounts for new clusters and services.}
|
|
115
|
+
`,
|
|
116
|
+
},
|
|
117
|
+
{ header : 'Options',
|
|
118
|
+
optionList : cliOptionList,
|
|
119
|
+
},
|
|
120
|
+
]
|
|
121
|
+
|
|
122
|
+
const choices = {
|
|
123
|
+
setupSecrets : 'Generate random k8s secrets (authz-postgres, npmrc, etc)',
|
|
124
|
+
setupRoles : 'Install leverege custom IAM roles',
|
|
125
|
+
setupServices : 'Create platform service accounts (api-server, emailer, etc)',
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const serviceManQs = [
|
|
129
|
+
{
|
|
130
|
+
type : 'checkbox',
|
|
131
|
+
name : 'sman.choices',
|
|
132
|
+
message : 'Select the service areas of interest',
|
|
133
|
+
choices : Object.values( choices )
|
|
134
|
+
},
|
|
135
|
+
]
|
|
136
|
+
|
|
137
|
+
export default class CommandLine {
|
|
138
|
+
constructor( options = {} ) {
|
|
139
|
+
/**
|
|
140
|
+
* Verify that node meets our minimum needs.
|
|
141
|
+
*/
|
|
142
|
+
try {
|
|
143
|
+
VersionCheck.validate( {
|
|
144
|
+
current : process.version, // this is the node version
|
|
145
|
+
minimum : '20.12',
|
|
146
|
+
maximum : '25', // must be less than this
|
|
147
|
+
preferred : '24.12',
|
|
148
|
+
} )
|
|
149
|
+
} catch ( err ) {
|
|
150
|
+
log( err )
|
|
151
|
+
process.exit( 1 )
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
this.args = commandLineArgs( cliOptionList, { camelCase : true, partial : true } )
|
|
155
|
+
this.runInquiry = Object.keys( this.args ).length === 0
|
|
156
|
+
|
|
157
|
+
if ( this.args.newK8S ) {
|
|
158
|
+
this.args.setupSecrets = true
|
|
159
|
+
this.args.setupRoles = true
|
|
160
|
+
this.args.setupServices = true
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
if ( this.args.version ) {
|
|
164
|
+
const packageVersion = JSON.parse(
|
|
165
|
+
fs.readFileSync( `${options.sourceTop}/../../package.json` ) // eslint-disable-line security/detect-non-literal-fs-filename
|
|
166
|
+
).version
|
|
167
|
+
log( `v${packageVersion}` )
|
|
168
|
+
process.exit( 0 )
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/* eslint-disable no-underscore-dangle */
|
|
172
|
+
if ( this.args._unknown ) {
|
|
173
|
+
log( commandLineUsage( sections ) )
|
|
174
|
+
log( chalk.red( `\n ***Error: unknown command line options: ${this.args._unknown}` ) )
|
|
175
|
+
process.exit( 1 )
|
|
176
|
+
}
|
|
177
|
+
/* eslint-enable no-underscore-dangle */
|
|
178
|
+
|
|
179
|
+
if ( this.args.help ) {
|
|
180
|
+
log( commandLineUsage( sections ) )
|
|
181
|
+
process.exit( 0 )
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
async init() {
|
|
186
|
+
if ( this.runInquiry ) {
|
|
187
|
+
const answers = await inquirer.prompt( serviceManQs )
|
|
188
|
+
answers.sman.choices.forEach( ( choice ) => {
|
|
189
|
+
// Do a reverse lookup of choices.key from user selections so a choice
|
|
190
|
+
// of 'IAM roles' from the choices object will yield an answer of
|
|
191
|
+
// 'setupRoles' in the args.
|
|
192
|
+
const answer = Object.keys( choices ).find( key => choices[key] === choice )
|
|
193
|
+
this.args[answer] = true
|
|
194
|
+
} )
|
|
195
|
+
this.answers = answers
|
|
196
|
+
}
|
|
197
|
+
return this
|
|
198
|
+
}
|
|
199
|
+
}
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import path from 'node:path'
|
|
2
|
+
import fs from 'node:fs/promises' /* eslint-disable security/detect-non-literal-fs-filename */
|
|
3
|
+
|
|
4
|
+
import chalk from 'chalk'
|
|
5
|
+
import { execa } from 'execa'
|
|
6
|
+
import inquirer from 'inquirer'
|
|
7
|
+
import SimpleGit from 'simple-git'
|
|
8
|
+
|
|
9
|
+
import { log, } from '../../Utils.mjs'
|
|
10
|
+
|
|
11
|
+
export default class Config {
|
|
12
|
+
constructor( options ) {
|
|
13
|
+
// we cannot async in the constructor - so use init to do the rest
|
|
14
|
+
this.configRoot = `${options.sourceTop}/config`
|
|
15
|
+
this.git = new SimpleGit()
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// expects a directory name containing text files with a .json extension
|
|
19
|
+
// returns an object with named entries based on the root file name
|
|
20
|
+
async loadJSON( jsonDirectory ) {
|
|
21
|
+
const jsonFiles = ( await fs.readdir( jsonDirectory ) )
|
|
22
|
+
.filter( el => path.extname( el ) === '.json' )
|
|
23
|
+
|
|
24
|
+
if ( !( jsonFiles?.length > 0 ) ) {
|
|
25
|
+
throw new Error( `missing JSON definition files in [${jsonDirectory}]` )
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const jsonObject = {}
|
|
29
|
+
for ( let i = 0; i < jsonFiles.length; i++ ) {
|
|
30
|
+
const jsonFile = jsonFiles[i]
|
|
31
|
+
/* eslint-disable-next-line no-await-in-loop */
|
|
32
|
+
const fileName = await fs.readFile( `${jsonDirectory}/${jsonFile}`, { encoding : 'utf8', flag : 'r' } )
|
|
33
|
+
const roleName = jsonFile.split( '.' )[0]
|
|
34
|
+
const jsonRole = JSON.parse( fileName )
|
|
35
|
+
jsonObject[roleName] = jsonRole
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return jsonObject
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Dumps the internal service-man config structures to the specified dir
|
|
42
|
+
// which may then be fed back into service-man via the --use-configs switch.
|
|
43
|
+
//
|
|
44
|
+
// Note: as of node 20 the node:fs.cp call was still experimental, but it
|
|
45
|
+
// has been around since node 16 so figured may as well use it.
|
|
46
|
+
async dump( dumpDir ) {
|
|
47
|
+
try {
|
|
48
|
+
const fileStat = await fs.stat( dumpDir )
|
|
49
|
+
if ( !fileStat.isDirectory() ) {
|
|
50
|
+
log( chalk.red.bold`
|
|
51
|
+
***Error: File already exists and it is not a directory
|
|
52
|
+
` + chalk.white`
|
|
53
|
+
In order to replicate service-man's internal configuration structure we need
|
|
54
|
+
to store the JSON files in a directory tree, but the specified dump target is
|
|
55
|
+
a flat file. Remove it and rerun the dump in order to proceed.
|
|
56
|
+
|
|
57
|
+
Remove => ` + chalk.yellow.bold( dumpDir ) )
|
|
58
|
+
process.exit( 1 )
|
|
59
|
+
}
|
|
60
|
+
} catch ( err ) {
|
|
61
|
+
// this file does not exist is a good thing
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
await fs.cp( // *Experimental*
|
|
65
|
+
this.configRoot,
|
|
66
|
+
dumpDir,
|
|
67
|
+
{
|
|
68
|
+
recursive : true,
|
|
69
|
+
filter : source => !source.endsWith( '.js' )
|
|
70
|
+
} )
|
|
71
|
+
|
|
72
|
+
const fh = await fs.open( `${dumpDir}/.nohelm`, 'a' )
|
|
73
|
+
await fh.close()
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
async init( CLI ) {
|
|
77
|
+
this.CLI = CLI
|
|
78
|
+
// allow the configRoot to be overridden from the CLI
|
|
79
|
+
const altConfigs = CLI.args.useConfigs
|
|
80
|
+
if ( altConfigs ) {
|
|
81
|
+
log( chalk.green`
|
|
82
|
+
*** Using alternate configs from => ` + chalk.yellow.bold( altConfigs ) )
|
|
83
|
+
this.configRoot = altConfigs
|
|
84
|
+
}
|
|
85
|
+
this.configDirs = ( await fs.readdir( this.configRoot, { withFileTypes : true } ) )
|
|
86
|
+
.filter( dirent => dirent.isDirectory( ) )
|
|
87
|
+
.map( dirent => dirent.name )
|
|
88
|
+
|
|
89
|
+
// get the top of the repo from git
|
|
90
|
+
this.gitTop = await this.git.revparse( [ '--show-toplevel' ] )
|
|
91
|
+
|
|
92
|
+
// verify this is executing from a platform-k8s branch
|
|
93
|
+
try {
|
|
94
|
+
this.overwhelm = `${this.gitTop}/overwhelm.yaml`
|
|
95
|
+
await fs.stat( this.overwhelm )
|
|
96
|
+
} catch ( err ) {
|
|
97
|
+
log( chalk.red.bold`
|
|
98
|
+
***Error: This does not look like a platform-k8s branch
|
|
99
|
+
` + chalk.yellow`
|
|
100
|
+
The service-man expects to operate from a platform-k8s branch to ensure
|
|
101
|
+
the proper handling of the kubernetes and gcloud context. Valid branches
|
|
102
|
+
of the platform-k8s repository should have an overwhelm.yaml file at their
|
|
103
|
+
root which absent from this location:
|
|
104
|
+
|
|
105
|
+
Missing => ` + chalk.red( err.path ) )
|
|
106
|
+
process.exit( 1 )
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// load up the GCP role definitions
|
|
110
|
+
this.rolesDir = `${this.configRoot}/iam-roles`
|
|
111
|
+
this.roles = await this.loadJSON( this.rolesDir )
|
|
112
|
+
|
|
113
|
+
// load up the known platform service account definitions
|
|
114
|
+
this.serviceAccountDir = CLI?.args?.setupServicesDir ?? `${this.configRoot}/service-accounts`
|
|
115
|
+
this.serviceAccounts = await this.loadJSON( this.serviceAccountDir )
|
|
116
|
+
|
|
117
|
+
// load up the random secrets definitions
|
|
118
|
+
this.secretsDir = `${this.configRoot}/secrets`
|
|
119
|
+
this.secrets = await this.loadJSON( this.secretsDir )
|
|
120
|
+
|
|
121
|
+
// if we're not running from helmup we need to check context
|
|
122
|
+
if ( !CLI.args.fromHelmup && !CLI.args.dumpConfigs ) {
|
|
123
|
+
try {
|
|
124
|
+
await execa( 'overwhelm', { stdio : 'inherit' } )
|
|
125
|
+
} catch ( err ) {
|
|
126
|
+
process.exit( err.exitCode )
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// if this is a new k8s then enable overwrites to avoid inquiry
|
|
131
|
+
this.overwrite = CLI.args.newK8S === true
|
|
132
|
+
|
|
133
|
+
// grab the current GCP config
|
|
134
|
+
const { stdout : gcloudConfig } = await execa( 'gcloud', [ 'config', 'list', '--format=json' ] )
|
|
135
|
+
this.gcloudConfig = JSON.parse( gcloudConfig )
|
|
136
|
+
|
|
137
|
+
// and the current k8s context which is gke_${project}_${region}_${cluster}
|
|
138
|
+
const { stdout : currentContext } = await execa( 'kubectl', [ 'config', 'current-context' ] )
|
|
139
|
+
const [ k8sPrefix, k8sProject, k8sRegion, k8sCluster ] = currentContext.split( '_' )
|
|
140
|
+
|
|
141
|
+
if ( k8sPrefix !== 'gke' ) {
|
|
142
|
+
throw Error( `Unknown cluster prefix [${k8sPrefix}] - expecting [gke]` )
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
this.k8sProject = k8sProject
|
|
146
|
+
this.k8sCluster = k8sCluster
|
|
147
|
+
this.k8sRegion = k8sRegion
|
|
148
|
+
|
|
149
|
+
this.initialized = true
|
|
150
|
+
|
|
151
|
+
return this
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
getRoles() { return this.roles }
|
|
155
|
+
|
|
156
|
+
getRoleNames() { return Object.keys( this.roles ) }
|
|
157
|
+
|
|
158
|
+
getRoleTitles() {
|
|
159
|
+
const roleNames = this.getRoleNames()
|
|
160
|
+
const titles = []
|
|
161
|
+
roleNames.forEach( name => titles.push( this.roles[name].title ) )
|
|
162
|
+
return titles
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
getRolesDir() { return this.rolesDir } // TODO: make smart look locally for existing roles in k8s project
|
|
166
|
+
|
|
167
|
+
getSecretsNames() { return Object.keys( this.secrets ) }
|
|
168
|
+
|
|
169
|
+
getServiceAccountNames() { return Object.keys( this.serviceAccounts ) }
|
|
170
|
+
|
|
171
|
+
getGcloudConfig() { return this.gcloudConfig }
|
|
172
|
+
|
|
173
|
+
getGcloudProject() { return this.gcloudConfig.core.project }
|
|
174
|
+
|
|
175
|
+
getGcloudCluster() { return this.gcloudConfig.container.cluster }
|
|
176
|
+
|
|
177
|
+
getK8sCluster() { return this.k8sCluster }
|
|
178
|
+
|
|
179
|
+
getK8sProject() { return this.k8sProject }
|
|
180
|
+
|
|
181
|
+
getK8sRegion() { return this.k8sRegion }
|
|
182
|
+
|
|
183
|
+
async askForRoles( serviceName ) {
|
|
184
|
+
const roleTitles = this.getRoleTitles()
|
|
185
|
+
const titlesInquiry = [
|
|
186
|
+
{
|
|
187
|
+
type : 'checkbox',
|
|
188
|
+
name : 'titles',
|
|
189
|
+
message : 'Select the roles necessary for the service',
|
|
190
|
+
choices : roleTitles,
|
|
191
|
+
pageSize : roleTitles.length,
|
|
192
|
+
}
|
|
193
|
+
]
|
|
194
|
+
const selection = await inquirer.prompt( titlesInquiry )
|
|
195
|
+
|
|
196
|
+
const roleNames = this.getRoleNames()
|
|
197
|
+
const selectedRoles = selection.titles.map( ( title ) => {
|
|
198
|
+
return roleNames.find( name => this.roles[name].title === title )
|
|
199
|
+
} )
|
|
200
|
+
|
|
201
|
+
return selectedRoles
|
|
202
|
+
}
|
|
203
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import chalk from 'chalk'
|
|
2
|
+
import coerce from 'semver/functions/coerce.js'
|
|
3
|
+
import semverLt from 'semver/functions/lt.js'
|
|
4
|
+
import satisfies from 'semver/functions/satisfies.js'
|
|
5
|
+
|
|
6
|
+
import { err, log, } from '../../Utils.mjs'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* This function verifies the specified version falls in this range:
|
|
10
|
+
*
|
|
11
|
+
* minimum >= current < maximum
|
|
12
|
+
*
|
|
13
|
+
* The params will be semver coerced where a version of 12 will be coerced
|
|
14
|
+
* to 12.0.0, a version of 12.18.4-beta.3 will be coerced to 12.18.4.
|
|
15
|
+
*
|
|
16
|
+
* Note that this function still has its references to node, but could be
|
|
17
|
+
* made entirely generic if need be.
|
|
18
|
+
*
|
|
19
|
+
* @param {Object} params
|
|
20
|
+
* @param {String} params.current - version to check
|
|
21
|
+
* @param {String} params.minimum - can be equal or greater to this
|
|
22
|
+
* @param {String} params.maximum - must be less than this
|
|
23
|
+
* @param {String} params.preferred - the most acceptable version
|
|
24
|
+
*/
|
|
25
|
+
function validate( params = {} ) {
|
|
26
|
+
const throwChalk = ( error ) => {
|
|
27
|
+
const errorStr = chalk.red.bold( '***ERROR service-man =>' )
|
|
28
|
+
err( chalk.yellow.bold( `\n${errorStr} ${error}` ) )
|
|
29
|
+
process.exit( 1 )
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if ( !params || !params.current || !params.minimum || !params.maximum ) {
|
|
33
|
+
throwChalk(
|
|
34
|
+
'current, minimum and maximum parameters are required by validate'
|
|
35
|
+
)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const coercedVersions = ( sems ) => {
|
|
39
|
+
return Object.keys( sems ).reduce( ( obj, key ) => {
|
|
40
|
+
const coerced = obj // avoid eslint warning
|
|
41
|
+
coerced[key] = coerce( sems[key] ).version
|
|
42
|
+
return coerced
|
|
43
|
+
}, {} )
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const { current, minimum, maximum, preferred } = coercedVersions( params )
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Verify that the current version falls within the accepted ranges.
|
|
50
|
+
*/
|
|
51
|
+
const rangeStr = `>=${minimum} <${maximum}`
|
|
52
|
+
if ( !satisfies( current, rangeStr ) ) {
|
|
53
|
+
throwChalk(
|
|
54
|
+
`Node version ${current} is outside the accepted range of ${rangeStr}`
|
|
55
|
+
)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Suggest upgrading to the currently recommended version.
|
|
60
|
+
*/
|
|
61
|
+
if ( preferred && semverLt( current, preferred ) ) {
|
|
62
|
+
// the hex #FF8800 gives us Orange
|
|
63
|
+
log(
|
|
64
|
+
chalk.hex( '#FF8800' ).bold( `
|
|
65
|
+
${chalk.yellow.bold( ' *** HEADS UP ***' )}
|
|
66
|
+
Running node version => ${chalk.yellow.bold( `v${current}` )} (which should work)
|
|
67
|
+
Preferred version is => ${chalk.green.bold( `v${preferred}` )}
|
|
68
|
+
|
|
69
|
+
Also, a reinstall of the build-tools may be necessary after any node upgrade
|
|
70
|
+
${chalk.cyan.bold( 'npm i -g @leverege/build-tools' )}
|
|
71
|
+
`
|
|
72
|
+
)
|
|
73
|
+
)
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export default {
|
|
78
|
+
validate,
|
|
79
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"description": "Leverege Big Query Writer",
|
|
3
|
+
"includedPermissions": [
|
|
4
|
+
"bigquery.datasets.create",
|
|
5
|
+
"bigquery.datasets.get",
|
|
6
|
+
"bigquery.jobs.create",
|
|
7
|
+
"bigquery.tables.create",
|
|
8
|
+
"bigquery.tables.get",
|
|
9
|
+
"bigquery.tables.updateData"
|
|
10
|
+
],
|
|
11
|
+
"stage": "BETA",
|
|
12
|
+
"title": "Leverege Big Query Writer"
|
|
13
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"description": "Leverege limited Cloud Functions Manager",
|
|
3
|
+
"includedPermissions": [
|
|
4
|
+
"cloudfunctions.functions.create",
|
|
5
|
+
"cloudfunctions.functions.delete",
|
|
6
|
+
"cloudfunctions.functions.get",
|
|
7
|
+
"cloudfunctions.functions.sourceCodeSet",
|
|
8
|
+
"cloudfunctions.functions.update"
|
|
9
|
+
],
|
|
10
|
+
"stage": "BETA",
|
|
11
|
+
"title": "Leverege Cloud Functions Manager"
|
|
12
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"description": "Leverege Firebase Messaging",
|
|
3
|
+
"includedPermissions": [
|
|
4
|
+
"cloudmessaging.messages.create",
|
|
5
|
+
"firebasenotifications.messages.create",
|
|
6
|
+
"firebasenotifications.messages.delete",
|
|
7
|
+
"firebasenotifications.messages.get",
|
|
8
|
+
"firebasenotifications.messages.list",
|
|
9
|
+
"firebasenotifications.messages.update"
|
|
10
|
+
],
|
|
11
|
+
"stage": "BETA",
|
|
12
|
+
"title": "Leverege Firebase Messaging"
|
|
13
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"description": "Leverege Pub/Sub",
|
|
3
|
+
"includedPermissions": [
|
|
4
|
+
"pubsub.subscriptions.consume",
|
|
5
|
+
"pubsub.subscriptions.create",
|
|
6
|
+
"pubsub.topics.attachSubscription",
|
|
7
|
+
"pubsub.topics.create",
|
|
8
|
+
"pubsub.topics.list",
|
|
9
|
+
"pubsub.topics.publish"
|
|
10
|
+
],
|
|
11
|
+
"stage": "BETA",
|
|
12
|
+
"title": "Leverege Pub/Sub"
|
|
13
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"description": "Leverege read / write access to Storage Objects",
|
|
3
|
+
"includedPermissions": [
|
|
4
|
+
"storage.buckets.create",
|
|
5
|
+
"storage.buckets.get",
|
|
6
|
+
"storage.buckets.getIamPolicy",
|
|
7
|
+
"storage.buckets.list",
|
|
8
|
+
"storage.buckets.update",
|
|
9
|
+
"storage.multipartUploads.abort",
|
|
10
|
+
"storage.multipartUploads.create",
|
|
11
|
+
"storage.multipartUploads.list",
|
|
12
|
+
"storage.multipartUploads.listParts",
|
|
13
|
+
"storage.objects.create",
|
|
14
|
+
"storage.objects.delete",
|
|
15
|
+
"storage.objects.get",
|
|
16
|
+
"storage.objects.getIamPolicy",
|
|
17
|
+
"storage.objects.list"
|
|
18
|
+
],
|
|
19
|
+
"stage": "BETA",
|
|
20
|
+
"title": "Leverege Storage Object Admin"
|
|
21
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"description": "Leverege read only access to Storage Objects",
|
|
3
|
+
"includedPermissions": [
|
|
4
|
+
"storage.buckets.get",
|
|
5
|
+
"storage.buckets.getIamPolicy",
|
|
6
|
+
"storage.buckets.list",
|
|
7
|
+
"storage.objects.get",
|
|
8
|
+
"storage.objects.getIamPolicy",
|
|
9
|
+
"storage.objects.list"
|
|
10
|
+
],
|
|
11
|
+
"stage": "BETA",
|
|
12
|
+
"title": "Leverege Storage Object Reader"
|
|
13
|
+
}
|