@hiiretail/gcp-infra-cli 0.86.1 → 0.87.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/generators/resources/pubsub/templates/pubsub/terragrunt.hcl +1 -1
- package/generators/resources/pubsub/templates/pubsub-dlq/terragrunt.hcl +1 -1
- package/generators/resources/spanner/append.js +26 -0
- package/generators/resources/spanner/index.js +70 -20
- package/generators/resources/spanner/templates/spanner/terragrunt.hcl +2 -2
- package/generators/resources/spanner/validate.js +28 -0
- package/package.json +1 -1
|
@@ -29,6 +29,6 @@ inputs = merge(<% if (createResource == 'topic') { %><% } else { %>
|
|
|
29
29
|
{
|
|
30
30
|
topic_labels = local.labels<% if (createResource == 'topic') { %><% } else { %>
|
|
31
31
|
subscription_labels = local.labels<% } %>
|
|
32
|
-
grant_token_creator =
|
|
32
|
+
grant_token_creator = true
|
|
33
33
|
}
|
|
34
34
|
)
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const yaml = require('js-yaml');
|
|
3
|
+
|
|
4
|
+
const appendToDatabasesYaml = (databasesYamlPath, newDbEntry) => {
|
|
5
|
+
const databases = [];
|
|
6
|
+
if (fs.existsSync(databasesYamlPath)) {
|
|
7
|
+
const existingContent = fs.readFileSync(databasesYamlPath, 'utf8');
|
|
8
|
+
const existingDatabases = yaml.load(existingContent).databases;
|
|
9
|
+
databases.push(...existingDatabases);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// Exclude empty fields from newDbEntry
|
|
13
|
+
const cleanNewDatabaseEntry = {
|
|
14
|
+
name: newDbEntry.name,
|
|
15
|
+
...(newDbEntry.ddl ? { ddl: newDbEntry.ddl } : {}),
|
|
16
|
+
...(newDbEntry.retentionPeriod ? { retentionPeriod: newDbEntry.retentionPeriod } : {}),
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
databases.push(cleanNewDatabaseEntry);
|
|
20
|
+
|
|
21
|
+
const newYamlContent = yaml.dump({ databases }, { lineWidth: -1 });
|
|
22
|
+
|
|
23
|
+
fs.writeFileSync(databasesYamlPath, newYamlContent, 'utf8');
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
module.exports = appendToDatabasesYaml;
|
|
@@ -1,24 +1,37 @@
|
|
|
1
1
|
const path = require('path');
|
|
2
2
|
const chalk = require('chalk');
|
|
3
|
+
const fs = require('fs');
|
|
3
4
|
const BaseGenerator = require('../../../src/BaseGenerator');
|
|
4
5
|
const { required } = require('../../../src/validators');
|
|
6
|
+
const { validName, validRetentionPeriod } = require('./validate');
|
|
7
|
+
const appendToDatabasesYaml = require('./append');
|
|
5
8
|
|
|
6
9
|
module.exports = class extends BaseGenerator {
|
|
7
10
|
prompting() {
|
|
8
11
|
const prompts = [
|
|
9
12
|
{
|
|
13
|
+
type: 'list',
|
|
14
|
+
name: 'resourceType',
|
|
15
|
+
message: 'Select the resource you want to create',
|
|
16
|
+
default: 'database',
|
|
17
|
+
choices: ['instance', 'database'],
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
when: (response) => response.resourceType === 'instance',
|
|
10
21
|
type: 'input',
|
|
11
22
|
name: 'instanceName',
|
|
12
|
-
message: 'Please provide a name for the instance
|
|
13
|
-
validate: required,
|
|
23
|
+
message: 'Please provide a name for the instance',
|
|
24
|
+
validate: (input) => required(input) && validName(input),
|
|
14
25
|
},
|
|
15
26
|
{
|
|
27
|
+
when: (response) => response.resourceType === 'instance',
|
|
16
28
|
type: 'input',
|
|
17
29
|
name: 'displayName',
|
|
18
|
-
message: 'Please provide the descriptive name for this instance. Unique per project
|
|
19
|
-
validate: required,
|
|
30
|
+
message: 'Please provide the descriptive name for this instance. Unique per project.',
|
|
31
|
+
validate: (input) => required(input) && validName(input),
|
|
20
32
|
},
|
|
21
33
|
{
|
|
34
|
+
when: (response) => response.resourceType === 'instance',
|
|
22
35
|
type: 'list',
|
|
23
36
|
name: 'instanceAllocation',
|
|
24
37
|
message: 'Select the specified config you want to add for the instance. Only one of these can be present in terraform node_count or processing_units',
|
|
@@ -26,34 +39,38 @@ module.exports = class extends BaseGenerator {
|
|
|
26
39
|
choices: ['processing_units', 'num_nodes'],
|
|
27
40
|
},
|
|
28
41
|
{
|
|
29
|
-
when: (response) => response.instanceAllocation === 'processing_units',
|
|
42
|
+
when: (response) => response.instanceAllocation === 'processing_units' && response.resourceType === 'instance',
|
|
30
43
|
type: 'input',
|
|
31
44
|
name: 'processingUnits',
|
|
32
45
|
message: 'Please provide the number of processing units allocated to the instance',
|
|
33
46
|
validate: required,
|
|
34
47
|
},
|
|
35
48
|
{
|
|
36
|
-
when: (response) => response.instanceAllocation === 'num_nodes',
|
|
49
|
+
when: (response) => response.instanceAllocation === 'num_nodes' && response.resourceType === 'instance',
|
|
37
50
|
type: 'input',
|
|
38
51
|
name: 'numNodes',
|
|
39
52
|
message: 'Please provide the number of nodes allocated to the instance',
|
|
40
53
|
validate: required,
|
|
41
54
|
},
|
|
42
55
|
{
|
|
56
|
+
when: (response) => response.resourceType === 'database',
|
|
43
57
|
type: 'input',
|
|
44
58
|
name: 'databaseName',
|
|
45
59
|
message: 'Please provide a name for the database',
|
|
46
|
-
validate: required,
|
|
60
|
+
validate: (input) => required(input) && validName(input),
|
|
47
61
|
},
|
|
48
62
|
{
|
|
63
|
+
when: (response) => response.resourceType === 'database',
|
|
49
64
|
type: 'input',
|
|
50
65
|
name: 'ddl',
|
|
51
66
|
message: 'Please provide an optional list of DDL statements to run inside the newly created database. Leave empty to add them later.',
|
|
52
67
|
},
|
|
53
68
|
{
|
|
69
|
+
when: (response) => response.resourceType === 'database',
|
|
54
70
|
type: 'input',
|
|
55
71
|
name: 'retentionPeriod',
|
|
56
72
|
message: 'Please provide version retention period. Maximum value 7d, possible values include 84000s, 1h, 2d. Leave empty for default value 1h.',
|
|
73
|
+
validate: (input) => required(input) && validRetentionPeriod(input),
|
|
57
74
|
},
|
|
58
75
|
];
|
|
59
76
|
|
|
@@ -64,6 +81,7 @@ module.exports = class extends BaseGenerator {
|
|
|
64
81
|
|
|
65
82
|
writing() {
|
|
66
83
|
const {
|
|
84
|
+
resourceType,
|
|
67
85
|
instanceName,
|
|
68
86
|
displayName,
|
|
69
87
|
instanceAllocation,
|
|
@@ -73,26 +91,58 @@ module.exports = class extends BaseGenerator {
|
|
|
73
91
|
} = this.answers;
|
|
74
92
|
|
|
75
93
|
['prod', 'staging'].forEach((env) => {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
94
|
+
const spannerPath = path.join('infra', env, 'spanner');
|
|
95
|
+
const databasesYamlPath = path.join(spannerPath, 'databases.yaml');
|
|
96
|
+
const specPath = path.join(spannerPath, 'spec.hcl');
|
|
97
|
+
|
|
98
|
+
if (!fs.existsSync(specPath)) {
|
|
99
|
+
['terragrunt.hcl', 'spec.hcl'].forEach((file) => {
|
|
100
|
+
this.fs.copyTpl(
|
|
101
|
+
this.templatePath(`spanner/${file}`),
|
|
102
|
+
this.destinationPath(`${spannerPath}/${file}`),
|
|
103
|
+
{
|
|
104
|
+
...this.answers,
|
|
105
|
+
resourceType,
|
|
106
|
+
env,
|
|
107
|
+
instanceName,
|
|
108
|
+
displayName,
|
|
109
|
+
instanceAllocation,
|
|
110
|
+
databaseName,
|
|
111
|
+
ddl,
|
|
112
|
+
retentionPeriod,
|
|
113
|
+
},
|
|
114
|
+
);
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
if (!fs.existsSync(databasesYamlPath) && resourceType === 'database') {
|
|
119
|
+
this.fs.copyTpl(
|
|
120
|
+
this.templatePath('spanner/databases.yaml'),
|
|
121
|
+
this.destinationPath(databasesYamlPath),
|
|
122
|
+
{
|
|
123
|
+
...this.answers,
|
|
124
|
+
databaseName,
|
|
125
|
+
ddl,
|
|
126
|
+
retentionPeriod,
|
|
127
|
+
},
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (fs.existsSync(databasesYamlPath) && resourceType === 'database') {
|
|
132
|
+
const newDatabaseEntry = {
|
|
133
|
+
name: databaseName,
|
|
86
134
|
ddl,
|
|
87
135
|
retentionPeriod,
|
|
88
|
-
}
|
|
89
|
-
|
|
136
|
+
};
|
|
137
|
+
appendToDatabasesYaml(databasesYamlPath, newDatabaseEntry);
|
|
138
|
+
}
|
|
90
139
|
});
|
|
91
140
|
}
|
|
92
141
|
|
|
93
142
|
end() {
|
|
94
143
|
this.log(`
|
|
95
|
-
${chalk.green('Your Cloud Spanner resources have now been created.
|
|
144
|
+
${chalk.green('Your Cloud Spanner resources have now been created.')}
|
|
145
|
+
${chalk.green('Make sure to create a database for your instance. Please add any other specifications supported by the module if needed')}
|
|
96
146
|
${chalk.green('1.')} Push this change in a feature branch and open a pull request.`);
|
|
97
147
|
}
|
|
98
148
|
};
|
|
@@ -22,9 +22,9 @@ locals {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
# These are the variables we have to pass in to use the module specified in the terragrunt configuration above
|
|
25
|
-
inputs = merge(
|
|
25
|
+
inputs = merge(<% if (resourceType == 'instance') { %><% } else { %>
|
|
26
26
|
yamldecode(
|
|
27
|
-
file("${get_terragrunt_dir()}/databases.yaml"))
|
|
27
|
+
file("${get_terragrunt_dir()}/databases.yaml")),<% } %>
|
|
28
28
|
local.spec_vars.locals,
|
|
29
29
|
local.project_vars.locals,
|
|
30
30
|
{
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
const validName = (input) => {
|
|
2
|
+
if (input.replace(/\s/g, '').length >= 6 && input.length <= 30) {
|
|
3
|
+
return { valid: true };
|
|
4
|
+
}
|
|
5
|
+
return { valid: false, message: 'Name must be between 6 and 30 characters in length' };
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
const validRetentionPeriod = (input) => {
|
|
9
|
+
const validFormats = /^(84000s|1h|2d|7d)$/;
|
|
10
|
+
|
|
11
|
+
if (input === '') {
|
|
12
|
+
// Empty input, using default value
|
|
13
|
+
return { valid: true };
|
|
14
|
+
}
|
|
15
|
+
if (validFormats.test(input)) {
|
|
16
|
+
return { valid: true };
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return {
|
|
20
|
+
valid: false,
|
|
21
|
+
message: 'Invalid retention period format. Possible values include 84000s, 1h, 2d, or leave empty for default value 1h',
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
module.exports = {
|
|
26
|
+
validName,
|
|
27
|
+
validRetentionPeriod,
|
|
28
|
+
};
|