@hiiretail/gcp-infra-generators 1.0.0 → 1.0.1
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/dist/generators/clan-resources/clan-project/index.js +89 -189
- package/dist/generators/common-resources/bigquery/index.js +172 -267
- package/dist/generators/common-resources/budget/index.js +67 -153
- package/dist/generators/common-resources/cloud-armor/index.js +17 -167
- package/dist/generators/common-resources/cloud-storage/index.js +96 -205
- package/dist/generators/common-resources/cloudsql/index.js +71 -177
- package/dist/generators/common-resources/cloudsql-database/index.js +40 -287
- package/dist/generators/common-resources/confluent-cluster/index.js +23 -132
- package/dist/generators/common-resources/datastore/index.js +48 -194
- package/dist/generators/common-resources/elastic-cloud/index.js +22 -132
- package/dist/generators/common-resources/elastic-index-policy/handle-yaml.js +76 -0
- package/dist/generators/common-resources/elastic-index-policy/index.js +131 -286
- package/dist/generators/common-resources/elastic-template/index.js +52 -162
- package/dist/generators/common-resources/firestore/index.js +93 -233
- package/dist/generators/common-resources/iam/index.js +35 -157
- package/dist/generators/common-resources/iam/valid-prefix.js +8 -0
- package/dist/generators/common-resources/kafka-connect/index.js +35 -144
- package/dist/generators/common-resources/kafka-topics/index.js +20 -129
- package/dist/generators/common-resources/kms/index.js +31 -141
- package/dist/generators/common-resources/memorystore/index.js +42 -328
- package/dist/generators/common-resources/monitoring/handle-yaml.js +49 -0
- package/dist/generators/common-resources/monitoring/index.js +144 -322
- package/dist/generators/common-resources/monitoring/validate.js +58 -0
- package/dist/generators/common-resources/pubsub/append.js +130 -0
- package/dist/generators/common-resources/pubsub/get-gcp-projects.js +34 -0
- package/dist/generators/common-resources/pubsub/handle-subscribers.js +68 -0
- package/dist/generators/common-resources/pubsub/index.js +194 -536
- package/dist/generators/common-resources/pubsub/validate.js +53 -0
- package/dist/generators/common-resources/scheduler/append.js +85 -0
- package/dist/generators/common-resources/scheduler/index.js +62 -249
- package/dist/generators/common-resources/spanner/append.js +31 -0
- package/dist/generators/common-resources/spanner/index.js +102 -269
- package/dist/generators/common-resources/spanner/validate.js +38 -0
- package/dist/generators/docs/rca/index.js +25 -135
- package/dist/generators/docs/runbook/index.js +16 -126
- package/dist/generators/docs/srb/index.js +33 -147
- package/dist/generators/docs/srb/run-docker.js +2 -0
- package/dist/generators/init/clan-infra/gcp-projects.js +47 -0
- package/dist/generators/init/clan-infra/index.js +95 -290
- package/dist/generators/init/clan-infra/tribe-clan-repo.js +38 -0
- package/dist/generators/init/clan-infra/validate.js +8 -0
- package/dist/generators/maintenance/manage-states/index.js +142 -219
- package/dist/generators/maintenance/update-modules/index.js +56 -155
- package/dist/generators/organization/clan-project/googlecloud.js +124 -0
- package/dist/generators/organization/clan-project/index.js +81 -303
- package/dist/node_modules/.package-lock.json +81 -23
- package/dist/package.json +45 -0
- package/dist/src/BaseGenerator.js +84 -0
- package/dist/src/SecretsGenerator.js +137 -0
- package/dist/src/cli.js +54 -255
- package/dist/src/dependency-check.js +48 -0
- package/dist/src/update-check.js +38 -0
- package/dist/src/validators.js +33 -0
- package/dist/src/yeoman.js +80 -0
- package/package.json +1 -2
|
@@ -1,170 +1,65 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
// src/validators.js
|
|
9
|
-
var require_validators = __commonJS({
|
|
10
|
-
"src/validators.js"(exports2, module2) {
|
|
11
|
-
var path = require("path");
|
|
12
|
-
module2.exports = {
|
|
13
|
-
chain: /* @__PURE__ */ __name((input, ...validators) => {
|
|
14
|
-
let msg = "";
|
|
15
|
-
validators.every((validator) => {
|
|
16
|
-
msg = validator(input);
|
|
17
|
-
return msg === true;
|
|
18
|
-
});
|
|
19
|
-
return msg === true ? true : msg;
|
|
20
|
-
}, "chain"),
|
|
21
|
-
filename: /* @__PURE__ */ __name((input) => {
|
|
22
|
-
if (!input) {
|
|
23
|
-
return true;
|
|
24
|
-
}
|
|
25
|
-
return path.basename(input) === input ? true : "Invalid filename";
|
|
26
|
-
}, "filename"),
|
|
27
|
-
maxLength: /* @__PURE__ */ __name((input, maxLength) => !input || input.length <= maxLength ? true : `Exceeds max \
|
|
28
|
-
length: ${maxLength}`, "maxLength"),
|
|
29
|
-
required: /* @__PURE__ */ __name((input) => {
|
|
30
|
-
const msg = "Required";
|
|
31
|
-
if (Array.isArray(input)) {
|
|
32
|
-
return input.length > 0 ? true : msg;
|
|
33
|
-
}
|
|
34
|
-
if (input) {
|
|
35
|
-
return input.trim().length > 0 ? true : msg;
|
|
36
|
-
}
|
|
37
|
-
return msg;
|
|
38
|
-
}, "required")
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
});
|
|
1
|
+
const axios = require('axios');
|
|
2
|
+
const fg = require('glob');
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const chalk = require('chalk');
|
|
5
|
+
const Separator = require('enquirer-separator');
|
|
6
|
+
const BaseGenerator = require('../../../src/BaseGenerator');
|
|
42
7
|
|
|
43
|
-
// src/BaseGenerator.js
|
|
44
|
-
var require_BaseGenerator = __commonJS({
|
|
45
|
-
"src/BaseGenerator.js"(exports2, module2) {
|
|
46
|
-
var Generator = require("yeoman-generator");
|
|
47
|
-
var path = require("path");
|
|
48
|
-
var fs2 = require("fs");
|
|
49
|
-
var inquirer = require("inquirer");
|
|
50
|
-
var { chain, required, filename } = require_validators();
|
|
51
|
-
module2.exports = class extends Generator {
|
|
52
|
-
constructor(args, opts) {
|
|
53
|
-
super(args, opts);
|
|
54
|
-
this.baseDir = path.resolve(path.join(__dirname, ".."));
|
|
55
|
-
this.destinationRoot(process.cwd());
|
|
56
|
-
const [command, generator] = opts.namespace.split(":").slice(-2);
|
|
57
|
-
this.generatorId = path.join(command, generator);
|
|
58
|
-
this.sourceRoot(
|
|
59
|
-
path.join(this.baseDir, "generators", this.generatorId, "templates")
|
|
60
|
-
);
|
|
61
|
-
this.copyDir = (templateDir, targetDir, answers = this.answers, skipIfExists = false) => {
|
|
62
|
-
if (skipIfExists && fs2.existsSync(targetDir)) {
|
|
63
|
-
return;
|
|
64
|
-
}
|
|
65
|
-
this.fs.copyTpl(
|
|
66
|
-
this.templatePath(`${templateDir}/**/*`),
|
|
67
|
-
this.destinationPath(targetDir),
|
|
68
|
-
answers
|
|
69
|
-
);
|
|
70
|
-
};
|
|
71
|
-
this.listSubDirectories = (parent) => fs2.readdirSync(parent).filter((f) => !f.startsWith(".")).filter((f) => fs2.
|
|
72
|
-
lstatSync(path.join(parent, f)).isDirectory()).sort((a, b) => a.localeCompare(b));
|
|
73
|
-
this.kebabCase = (input) => input.replace(/\s|_/g, "-");
|
|
74
|
-
this.chooseOrCreatePrompts = (name, getChoicesDirectory) => [
|
|
75
|
-
{
|
|
76
|
-
when: /* @__PURE__ */ __name((answers) => fs2.existsSync(getChoicesDirectory(answers)), "when"),
|
|
77
|
-
type: "list",
|
|
78
|
-
name,
|
|
79
|
-
message: `Choose ${name}`,
|
|
80
|
-
store: true,
|
|
81
|
-
choices: /* @__PURE__ */ __name((answers) => [
|
|
82
|
-
...this.listSubDirectories(getChoicesDirectory(answers)),
|
|
83
|
-
new inquirer.Separator(),
|
|
84
|
-
`Create new ${name}`
|
|
85
|
-
], "choices"),
|
|
86
|
-
validate: required,
|
|
87
|
-
filter: this.kebabCase
|
|
88
|
-
},
|
|
89
|
-
{
|
|
90
|
-
when: /* @__PURE__ */ __name((answers) => !fs2.existsSync(getChoicesDirectory(answers)) || answers[name] ===
|
|
91
|
-
`Create-new-${name}`, "when"),
|
|
92
|
-
type: "input",
|
|
93
|
-
name: `new-${name}`,
|
|
94
|
-
message: `New ${name} name`,
|
|
95
|
-
store: false,
|
|
96
|
-
validate: /* @__PURE__ */ __name((input) => chain(input, required, filename), "validate"),
|
|
97
|
-
filter: this.kebabCase
|
|
98
|
-
},
|
|
99
|
-
{
|
|
100
|
-
when: /* @__PURE__ */ __name((answers) => !fs2.existsSync(getChoicesDirectory(answers)) || answers[name] ===
|
|
101
|
-
"Create-new-tribe", "when"),
|
|
102
|
-
type: "input",
|
|
103
|
-
name: "costCenter",
|
|
104
|
-
message: "Please provide the Cost Center of the Tribe",
|
|
105
|
-
store: false,
|
|
106
|
-
validate: /* @__PURE__ */ __name((input) => chain(input, required, filename), "validate"),
|
|
107
|
-
filter: this.kebabCase
|
|
108
|
-
}
|
|
109
|
-
];
|
|
110
|
-
}
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
// generators/maintenance/update-modules/index.js
|
|
116
|
-
var axios = require("axios");
|
|
117
|
-
var fg = require("glob");
|
|
118
|
-
var fs = require("fs");
|
|
119
|
-
var chalk = require("chalk");
|
|
120
|
-
var Separator = require("enquirer-separator");
|
|
121
|
-
var BaseGenerator = require_BaseGenerator();
|
|
122
8
|
module.exports = class extends BaseGenerator {
|
|
123
9
|
prompting() {
|
|
124
10
|
const prompts = [
|
|
125
11
|
{
|
|
126
|
-
type:
|
|
127
|
-
name:
|
|
128
|
-
message:
|
|
12
|
+
type: 'list',
|
|
13
|
+
name: 'moduleName',
|
|
14
|
+
message: 'Select Terraform module for update',
|
|
129
15
|
store: true,
|
|
130
|
-
choices:
|
|
131
|
-
const regex =
|
|
132
|
-
|
|
133
|
-
const
|
|
16
|
+
choices: async () => {
|
|
17
|
+
const regex =
|
|
18
|
+
/source = "(.+?)?github.com\/(.+?\/.+?)(\/.+)?\?ref=(.+)"/;
|
|
19
|
+
const hclFiles = fg.sync('**/terragrunt.hcl', { dot: false });
|
|
20
|
+
const foundModules = new Set();
|
|
21
|
+
|
|
134
22
|
hclFiles.forEach((hclFile) => {
|
|
135
|
-
const content = fs.readFileSync(hclFile,
|
|
23
|
+
const content = fs.readFileSync(hclFile, 'utf8');
|
|
136
24
|
const match = regex.exec(content);
|
|
137
25
|
if (match) {
|
|
138
26
|
foundModules.add(match[2]);
|
|
139
27
|
}
|
|
140
28
|
});
|
|
141
|
-
|
|
142
|
-
|
|
29
|
+
|
|
30
|
+
return Array.from(foundModules)
|
|
31
|
+
.sort((a, b) => a.localeCompare(b))
|
|
32
|
+
.concat([new Separator('------')]);
|
|
33
|
+
},
|
|
143
34
|
},
|
|
144
35
|
{
|
|
145
|
-
type:
|
|
146
|
-
name:
|
|
147
|
-
message:
|
|
36
|
+
type: 'list',
|
|
37
|
+
name: 'moduleTag',
|
|
38
|
+
message: 'Select module version for update to',
|
|
148
39
|
store: true,
|
|
149
|
-
choices:
|
|
40
|
+
choices: async (response) => {
|
|
150
41
|
const tagsResponse = await axios.get(
|
|
151
|
-
`https://api.github.com/repos/${response.moduleName}/tags
|
|
42
|
+
`https://api.github.com/repos/${response.moduleName}/tags`,
|
|
152
43
|
);
|
|
153
|
-
return tagsResponse.data
|
|
154
|
-
|
|
44
|
+
return tagsResponse.data
|
|
45
|
+
.map((el) => el.name)
|
|
46
|
+
.concat([new Separator('------')]);
|
|
47
|
+
},
|
|
155
48
|
},
|
|
49
|
+
|
|
156
50
|
{
|
|
157
|
-
type:
|
|
158
|
-
name:
|
|
159
|
-
message:
|
|
160
|
-
choices:
|
|
51
|
+
type: 'checkbox',
|
|
52
|
+
name: 'files',
|
|
53
|
+
message: 'Select Terragrunt files to update the module version',
|
|
54
|
+
choices: async (response) => {
|
|
161
55
|
const regex = new RegExp(
|
|
162
|
-
`source = "(.+/)?(${response.moduleName})(/.+)?\\?ref=(.+)"
|
|
56
|
+
`source = "(.+/)?(${response.moduleName})(/.+)?\\?ref=(.+)"`,
|
|
163
57
|
);
|
|
164
|
-
const hclFiles = fg.sync(
|
|
58
|
+
const hclFiles = fg.sync('**/terragrunt.hcl', { dot: false });
|
|
165
59
|
const matchedFiles = [];
|
|
60
|
+
|
|
166
61
|
hclFiles.forEach((hclFile) => {
|
|
167
|
-
const content = fs.readFileSync(hclFile,
|
|
62
|
+
const content = fs.readFileSync(hclFile, 'utf8');
|
|
168
63
|
const match = regex.exec(content);
|
|
169
64
|
if (match) {
|
|
170
65
|
const currentTag = match[4];
|
|
@@ -172,43 +67,49 @@ module.exports = class extends BaseGenerator {
|
|
|
172
67
|
matchedFiles.push({
|
|
173
68
|
name: `${currentTag} => ${response.moduleTag}: ${hclFile}`,
|
|
174
69
|
value: hclFile,
|
|
175
|
-
checked: true
|
|
70
|
+
checked: true,
|
|
176
71
|
});
|
|
177
72
|
}
|
|
178
73
|
}
|
|
179
74
|
});
|
|
75
|
+
|
|
180
76
|
if (matchedFiles.length === 0) {
|
|
181
77
|
this.log(
|
|
182
|
-
`There is no files left to update. All files uses ${chalk.cyan(response.moduleTag)} version of ${chalk.cyan(
|
|
183
|
-
response.moduleName)} module`
|
|
78
|
+
`There is no files left to update. All files uses ${chalk.cyan(response.moduleTag)} version of ${chalk.cyan(response.moduleName)} module`,
|
|
184
79
|
);
|
|
185
80
|
process.exit();
|
|
186
81
|
}
|
|
187
|
-
return matchedFiles
|
|
188
|
-
|
|
189
|
-
|
|
82
|
+
return matchedFiles
|
|
83
|
+
.toSorted((a, b) => (a.value > b.value ? 1 : -1))
|
|
84
|
+
.concat([new Separator('------')]);
|
|
85
|
+
},
|
|
86
|
+
},
|
|
190
87
|
];
|
|
88
|
+
|
|
191
89
|
return this.prompt(prompts).then((props) => {
|
|
192
90
|
this.answers = props;
|
|
193
91
|
});
|
|
194
92
|
}
|
|
93
|
+
|
|
195
94
|
writing() {
|
|
196
95
|
const regex = new RegExp(
|
|
197
|
-
`(source = "(.+/)?(${this.answers.moduleName})(/.+)?\\?ref=)(.+)"
|
|
96
|
+
`(source = "(.+/)?(${this.answers.moduleName})(/.+)?\\?ref=)(.+)"`,
|
|
198
97
|
);
|
|
199
98
|
this.answers.files.forEach((hclFile) => {
|
|
200
|
-
const content = fs.readFileSync(hclFile,
|
|
99
|
+
const content = fs.readFileSync(hclFile, 'utf8');
|
|
100
|
+
// const newContent = content.replace(regex, '$1' + this.answers.moduleTag + '"');
|
|
201
101
|
const newContent = content.replace(regex, `$1${this.answers.moduleTag}"`);
|
|
202
|
-
fs.writeFileSync(hclFile, newContent,
|
|
102
|
+
fs.writeFileSync(hclFile, newContent, 'utf8');
|
|
203
103
|
});
|
|
204
104
|
}
|
|
105
|
+
|
|
205
106
|
end() {
|
|
206
107
|
const { moduleName, moduleTag, files } = this.answers;
|
|
207
108
|
this.log(
|
|
208
|
-
`In next files ${chalk.green(moduleName)} module version was updated to ${chalk.green(moduleTag)} version
|
|
109
|
+
`In next files ${chalk.green(moduleName)} module version was updated to ${chalk.green(moduleTag)} version:`,
|
|
209
110
|
);
|
|
210
111
|
files.forEach((f) => this.log(chalk.cyan(f)));
|
|
211
|
-
this.log(
|
|
112
|
+
this.log('Next update infrastructure using pipeline or manually');
|
|
212
113
|
this.log('Note: Always use "git diff" before commit or apply the changes');
|
|
213
114
|
}
|
|
214
115
|
};
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
// List of APIs to include in the project.yaml file. Entries will be
|
|
2
|
+
// enabled depending on user selections in Yeoman.
|
|
3
|
+
const availableApis = [
|
|
4
|
+
{
|
|
5
|
+
value: 'automl.googleapis.com',
|
|
6
|
+
name: 'Cloud AutoML API',
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
value: 'bigtable.googleapis.com',
|
|
10
|
+
name: 'Cloud Bigtable',
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
value: 'bigquery.googleapis.com',
|
|
14
|
+
name: 'Cloud BigQuery',
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
value: 'cloudapis.googleapis.com',
|
|
18
|
+
name: 'Google Cloud APIs',
|
|
19
|
+
enabled: true,
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
value: 'clouddeploy.googleapis.com',
|
|
23
|
+
name: 'Cloud Deploy API',
|
|
24
|
+
enabled: true,
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
value: 'cloudfunctions.googleapis.com',
|
|
28
|
+
name: 'Cloud Functions API',
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
value: 'cloudresourcemanager.googleapis.com',
|
|
32
|
+
name: 'Cloud Resource Manager API',
|
|
33
|
+
enabled: true,
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
value: 'compute.googleapis.com',
|
|
37
|
+
name: 'Compute Engine API',
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
value: 'container.googleapis.com',
|
|
41
|
+
name: 'Kubernetes',
|
|
42
|
+
enabled: true,
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
value: 'containerregistry.googleapis.com',
|
|
46
|
+
name: 'Container Registry',
|
|
47
|
+
enabled: true,
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
value: 'dataflow.googleapis.com',
|
|
51
|
+
name: 'Dataflow API',
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
value: 'dns.googleapis.com',
|
|
55
|
+
name: 'Cloud DNS API',
|
|
56
|
+
enabled: true,
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
value: 'firestore.googleapis.com',
|
|
60
|
+
name: 'Cloud Firestore',
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
value: 'monitoring.googleapis.com',
|
|
64
|
+
name: 'Stackdriver Monitoring API',
|
|
65
|
+
enabled: true,
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
value: 'pubsub.googleapis.com',
|
|
69
|
+
name: 'Cloud Pub/Sub API',
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
value: 'redis.googleapis.com',
|
|
73
|
+
name: 'Memorystore (Redis)',
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
value: 'run.googleapis.com',
|
|
77
|
+
name: 'Cloud Run API',
|
|
78
|
+
enabled: true,
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
value: 'secretmanager.googleapis.com',
|
|
82
|
+
name: 'Secret Manager API',
|
|
83
|
+
enabled: true,
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
value: 'spanner.googleapis.com',
|
|
87
|
+
name: 'Cloud Spanner API',
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
value: 'storage-api.googleapis.com',
|
|
91
|
+
name: 'Cloud Storage',
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
value: 'sqladmin.googleapis.com',
|
|
95
|
+
name: 'Cloud SQL',
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
value: 'servicenetworking.googleapis.com',
|
|
99
|
+
name: 'Service Networking API',
|
|
100
|
+
enabled: true,
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
value: 'vpcaccess.googleapis.com',
|
|
104
|
+
name: 'Serverless VPC Access API',
|
|
105
|
+
enabled: true,
|
|
106
|
+
},
|
|
107
|
+
];
|
|
108
|
+
|
|
109
|
+
const apisYaml = (resources = []) =>
|
|
110
|
+
availableApis
|
|
111
|
+
.map((entry) => ({
|
|
112
|
+
...entry,
|
|
113
|
+
enabled: entry.enabled || resources.includes(entry.value),
|
|
114
|
+
}))
|
|
115
|
+
.reduce(
|
|
116
|
+
(acc, entry) =>
|
|
117
|
+
`${acc}${entry.enabled ? ' -' : '# -'} ${entry.value.padEnd(60, ' ')} # ${entry.name}\n`,
|
|
118
|
+
'',
|
|
119
|
+
)
|
|
120
|
+
.trimEnd();
|
|
121
|
+
|
|
122
|
+
module.exports = {
|
|
123
|
+
apisYaml,
|
|
124
|
+
};
|