@hiiretail/gcp-infra-cli 0.74.0 → 0.75.2
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 +1 -1
- package/generators/resources/pubsub/append.js +26 -4
- package/generators/resources/pubsub/handle-subscribers.js +24 -5
- package/generators/resources/pubsub/index.js +25 -2
- package/generators/resources/pubsub/templates/pubsub/subscribers.yaml +4 -2
- package/generators/resources/pubsub/templates/pubsub-dlq/terragrunt.hcl +41 -0
- package/generators/resources/pubsub/templates/pubsub-external/subscribers.yaml +4 -2
- package/generators/resources/spanner/index.js +7 -0
- package/generators/resources/spanner/templates/spanner/spec.hcl +4 -0
- package/generators/resources/spanner/templates/spanner/terragrunt.hcl +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
const yaml = require('js-yaml');
|
|
2
2
|
const fs = require('fs');
|
|
3
3
|
|
|
4
|
-
const
|
|
4
|
+
const addDLQ = async (yamlArray, env, dlqTopic) => {
|
|
5
|
+
if (env === 'prod') {
|
|
6
|
+
/* eslint-disable */
|
|
7
|
+
yamlArray[0].dead_letter_topic = dlqTopic;
|
|
8
|
+
/* eslint-enable */
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const appendNotIncludePull = async (inputs, subscriptionFilePath, dlqTopic) => {
|
|
5
13
|
const pullArray = [];
|
|
6
14
|
|
|
7
15
|
pullArray.push(
|
|
@@ -12,11 +20,17 @@ const appendNotIncludePull = async (inputs, subscriptionFilePath) => {
|
|
|
12
20
|
},
|
|
13
21
|
);
|
|
14
22
|
|
|
23
|
+
await addDLQ(pullArray, inputs.env, dlqTopic);
|
|
15
24
|
const yamlPullArray = yaml.dump(pullArray);
|
|
16
25
|
fs.appendFileSync(subscriptionFilePath, `pull_subscriptions:\n${yamlPullArray}`);
|
|
17
26
|
};
|
|
18
27
|
|
|
19
|
-
const appendIncludePull = async (
|
|
28
|
+
const appendIncludePull = async (
|
|
29
|
+
fileContent,
|
|
30
|
+
originalContentYaml,
|
|
31
|
+
subscriptionFilePath,
|
|
32
|
+
input,
|
|
33
|
+
dlqTopic) => {
|
|
20
34
|
if (fileContent.includes('pull_subscriptions')) {
|
|
21
35
|
const pullArray = Object.values(originalContentYaml.pull_subscriptions);
|
|
22
36
|
const yamlPullArray = yaml.dump(pullArray);
|
|
@@ -33,6 +47,7 @@ const appendIncludePull = async (fileContent, originalContentYaml, subscriptionF
|
|
|
33
47
|
},
|
|
34
48
|
);
|
|
35
49
|
|
|
50
|
+
await addDLQ(newPullArray, input.env, dlqTopic);
|
|
36
51
|
const finalYamlPullArray = yaml.dump(newPullArray);
|
|
37
52
|
fs.appendFileSync(subscriptionFilePath, finalYamlPullArray);
|
|
38
53
|
|
|
@@ -43,7 +58,7 @@ const appendIncludePull = async (fileContent, originalContentYaml, subscriptionF
|
|
|
43
58
|
}
|
|
44
59
|
};
|
|
45
60
|
|
|
46
|
-
const appendNotIncludePush = async (inputs, subscriptionFilePath) => {
|
|
61
|
+
const appendNotIncludePush = async (inputs, subscriptionFilePath, dlqTopic) => {
|
|
47
62
|
const pushArray = [];
|
|
48
63
|
|
|
49
64
|
pushArray.push(
|
|
@@ -56,11 +71,17 @@ const appendNotIncludePush = async (inputs, subscriptionFilePath) => {
|
|
|
56
71
|
},
|
|
57
72
|
);
|
|
58
73
|
|
|
74
|
+
await addDLQ(pushArray, inputs.env, dlqTopic);
|
|
59
75
|
const yamlPushArray = yaml.dump(pushArray);
|
|
60
76
|
fs.appendFileSync(subscriptionFilePath, `push_subscriptions:\n${yamlPushArray}`);
|
|
61
77
|
};
|
|
62
78
|
|
|
63
|
-
const appendIncludePush = async (
|
|
79
|
+
const appendIncludePush = async (
|
|
80
|
+
fileContent,
|
|
81
|
+
originalContentYaml,
|
|
82
|
+
subscriptionFilePath,
|
|
83
|
+
input,
|
|
84
|
+
dlqTopic) => {
|
|
64
85
|
if (fileContent.includes('push_subscriptions')) {
|
|
65
86
|
const pushArray = Object.values(originalContentYaml.push_subscriptions);
|
|
66
87
|
const yamlPushArray = yaml.dump(pushArray);
|
|
@@ -78,6 +99,7 @@ const appendIncludePush = async (fileContent, originalContentYaml, subscriptionF
|
|
|
78
99
|
expiration_policy: '',
|
|
79
100
|
},
|
|
80
101
|
);
|
|
102
|
+
await addDLQ(newPushArray, input.env, dlqTopic);
|
|
81
103
|
const yamlPushArray = yaml.dump(newPushArray);
|
|
82
104
|
fs.appendFileSync(subscriptionFilePath, yamlPushArray);
|
|
83
105
|
|
|
@@ -4,7 +4,13 @@ const {
|
|
|
4
4
|
appendNotIncludePull, appendIncludePull, appendNotIncludePush, appendIncludePush,
|
|
5
5
|
} = require('./append');
|
|
6
6
|
|
|
7
|
-
const handleSubscribers = async (
|
|
7
|
+
const handleSubscribers = async (
|
|
8
|
+
env,
|
|
9
|
+
answers,
|
|
10
|
+
oidcEmail,
|
|
11
|
+
pushEndpoint,
|
|
12
|
+
subscriptionFilePath,
|
|
13
|
+
dlqTopic) => {
|
|
8
14
|
const {
|
|
9
15
|
subscriberName,
|
|
10
16
|
existingTopic,
|
|
@@ -22,22 +28,35 @@ const handleSubscribers = async (env, answers, oidcEmail, pushEndpoint, subscrip
|
|
|
22
28
|
audience,
|
|
23
29
|
oidcEmail,
|
|
24
30
|
pushEndpoint,
|
|
31
|
+
dlqTopic,
|
|
25
32
|
};
|
|
26
33
|
|
|
27
34
|
if (pushOrPull === 'pull') {
|
|
28
35
|
if (subscriptionFileContent.length === 0 || !subscriptionFileContent.includes('pull_subscriptions')) {
|
|
29
|
-
await appendNotIncludePull(inputs, subscriptionFilePath);
|
|
36
|
+
await appendNotIncludePull(inputs, subscriptionFilePath, dlqTopic);
|
|
30
37
|
} else {
|
|
31
38
|
const originalContentYaml = yaml.load(subscriptionFileContent);
|
|
32
39
|
const fileContent = subscriptionFileContent;
|
|
33
|
-
await appendIncludePull(
|
|
40
|
+
await appendIncludePull(
|
|
41
|
+
fileContent,
|
|
42
|
+
originalContentYaml,
|
|
43
|
+
subscriptionFilePath,
|
|
44
|
+
inputs,
|
|
45
|
+
dlqTopic,
|
|
46
|
+
);
|
|
34
47
|
}
|
|
35
48
|
} else if (subscriptionFileContent.length === 0 || !subscriptionFileContent.includes('push_subscriptions')) {
|
|
36
|
-
await appendNotIncludePush(inputs, subscriptionFilePath);
|
|
49
|
+
await appendNotIncludePush(inputs, subscriptionFilePath, dlqTopic);
|
|
37
50
|
} else {
|
|
38
51
|
const originalContentYaml = yaml.load(subscriptionFileContent);
|
|
39
52
|
const fileContent = subscriptionFileContent;
|
|
40
|
-
await appendIncludePush(
|
|
53
|
+
await appendIncludePush(
|
|
54
|
+
fileContent,
|
|
55
|
+
originalContentYaml,
|
|
56
|
+
subscriptionFilePath,
|
|
57
|
+
inputs,
|
|
58
|
+
dlqTopic,
|
|
59
|
+
);
|
|
41
60
|
}
|
|
42
61
|
};
|
|
43
62
|
|
|
@@ -170,6 +170,18 @@ module.exports = class extends BaseGenerator {
|
|
|
170
170
|
externalSub,
|
|
171
171
|
} = this.answers;
|
|
172
172
|
|
|
173
|
+
const dlqTopicName = `${getProjectId('prod').split('-')[0]}-common-dlq`;
|
|
174
|
+
let dlqTopic = `projects/${getProjectId('prod')}/topics/${dlqTopicName}`;
|
|
175
|
+
|
|
176
|
+
const dlqTopicDirPath = path.join(process.cwd(), 'infra', 'prod', 'pubsub', dlqTopicName);
|
|
177
|
+
this.fs.copyTpl(
|
|
178
|
+
this.templatePath('pubsub-dlq/terragrunt.hcl'),
|
|
179
|
+
this.destinationPath(`${dlqTopicDirPath}/terragrunt.hcl`),
|
|
180
|
+
{
|
|
181
|
+
...this.answers,
|
|
182
|
+
},
|
|
183
|
+
);
|
|
184
|
+
|
|
173
185
|
['prod', 'staging'].forEach(async (env) => {
|
|
174
186
|
if (createResource === 'topic') {
|
|
175
187
|
const topicDirPath = path.join(process.cwd(), 'infra', env, 'pubsub', topicName);
|
|
@@ -182,6 +194,7 @@ module.exports = class extends BaseGenerator {
|
|
|
182
194
|
env,
|
|
183
195
|
topicName,
|
|
184
196
|
subscriberName,
|
|
197
|
+
dlqTopic,
|
|
185
198
|
},
|
|
186
199
|
);
|
|
187
200
|
});
|
|
@@ -212,6 +225,7 @@ module.exports = class extends BaseGenerator {
|
|
|
212
225
|
audience,
|
|
213
226
|
oidcEmail,
|
|
214
227
|
pushEndpoint,
|
|
228
|
+
dlqTopic,
|
|
215
229
|
},
|
|
216
230
|
);
|
|
217
231
|
}
|
|
@@ -228,7 +242,7 @@ module.exports = class extends BaseGenerator {
|
|
|
228
242
|
);
|
|
229
243
|
});
|
|
230
244
|
|
|
231
|
-
await handleSubscribers(env, this.answers, oidcEmail, pushEndpoint, `${subscriptionDirPath}/subscribers.yaml
|
|
245
|
+
await handleSubscribers(env, this.answers, oidcEmail, pushEndpoint, `${subscriptionDirPath}/subscribers.yaml`, dlqTopic);
|
|
232
246
|
}
|
|
233
247
|
if (createResource === 'subscription' && externalSub === 'yes') {
|
|
234
248
|
const externalDirPath = path.join(process.cwd(), 'infra', env, 'pubsub', existingTopic, clanName);
|
|
@@ -259,6 +273,7 @@ module.exports = class extends BaseGenerator {
|
|
|
259
273
|
oidcEmail = `${oidcName}@${stagingProjectIdConsumer}.iam.gserviceaccount.com`;
|
|
260
274
|
} else {
|
|
261
275
|
oidcEmail = `${oidcName}@${prodProjectIdConsumer}.iam.gserviceaccount.com`;
|
|
276
|
+
dlqTopic = `projects/${prodProjectIdConsumer}/topics/${prodProjectIdConsumer.split('-')[0]}-common-dlq`;
|
|
262
277
|
}
|
|
263
278
|
if (!fs.existsSync(externalSubPath)) {
|
|
264
279
|
fs.writeFileSync(externalSubPath, '');
|
|
@@ -273,11 +288,19 @@ module.exports = class extends BaseGenerator {
|
|
|
273
288
|
audience,
|
|
274
289
|
oidcEmail,
|
|
275
290
|
pushEndpoint,
|
|
291
|
+
dlqTopic,
|
|
276
292
|
},
|
|
277
293
|
);
|
|
278
294
|
}
|
|
279
295
|
|
|
280
|
-
await handleSubscribers(
|
|
296
|
+
await handleSubscribers(
|
|
297
|
+
env,
|
|
298
|
+
this.answers,
|
|
299
|
+
oidcEmail,
|
|
300
|
+
pushEndpoint,
|
|
301
|
+
externalSubPath,
|
|
302
|
+
dlqTopic,
|
|
303
|
+
);
|
|
281
304
|
}
|
|
282
305
|
});
|
|
283
306
|
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
<% if (createResource == 'topic') { %><% } %><% if (createResource == 'subscription' && pushOrPull == 'push') { %>push_subscriptions:
|
|
2
2
|
- name: "<%-existingTopic%>+<%-subscriberName%>"
|
|
3
|
-
push_endpoint: "<%-pushEndpoint%>"
|
|
3
|
+
push_endpoint: "<%-pushEndpoint%>" <% if (env == 'prod') { %>
|
|
4
|
+
dead_letter_topic: "<%-dlqTopic%>" <% } %>
|
|
4
5
|
oidc_service_account_email: "<%-oidcEmail%>"
|
|
5
6
|
audience: "<%-audience%>"
|
|
6
7
|
expiration_policy: ""<% } %><% if (createResource == 'subscription' && pushOrPull == 'pull') { %>pull_subscriptions:
|
|
7
8
|
- name: "<%-existingTopic%>+<%-subscriberName%>"
|
|
8
|
-
ack_deadline_seconds: "60"
|
|
9
|
+
ack_deadline_seconds: "60" <% if (env == 'prod') { %>
|
|
10
|
+
dead_letter_topic: "<%-dlqTopic%>" <% } %>
|
|
9
11
|
expiration_policy: ""<% } %>
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Terragrunt will copy the Terraform configurations specified by the source parameter, along with any files in the
|
|
2
|
+
# working directory, into a temporary folder, and execute your Terraform commands in that folder.
|
|
3
|
+
terraform {
|
|
4
|
+
source = "git::https://github.com/terraform-google-modules/terraform-google-pubsub//?ref=v3.0.0"
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
# Include all settings from the root terragrunt.hcl file
|
|
8
|
+
include {
|
|
9
|
+
path = find_in_parent_folders("terragrunt_root.hcl")
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
locals {
|
|
13
|
+
project_vars = read_terragrunt_config(find_in_parent_folders("project.hcl"))
|
|
14
|
+
common_vars = read_terragrunt_config(find_in_parent_folders("common.hcl"))
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
# These are the variables we have to pass in to use the module specified in the terragrunt configuration above
|
|
18
|
+
inputs = merge (
|
|
19
|
+
local.project_vars.locals,
|
|
20
|
+
{
|
|
21
|
+
topic = "${local.common_vars.locals.clan_name}-common-dlq"
|
|
22
|
+
create_subscriptions = true
|
|
23
|
+
create_topic = true
|
|
24
|
+
push_subscriptions = [
|
|
25
|
+
{
|
|
26
|
+
name = "dlq-message-handler-subscription",
|
|
27
|
+
push_endpoint = "https://europe-west1-sre-prod-5462.cloudfunctions.net/dlq-message-handler",
|
|
28
|
+
audience = "https://europe-west1-sre-prod-5462.cloudfunctions.net/dlq-message-handler",
|
|
29
|
+
expiration_policy = "",
|
|
30
|
+
oidc_service_account_email = "pubsub-dlq-handler@${local.project_vars.locals.project_id}.iam.gserviceaccount.com",
|
|
31
|
+
},
|
|
32
|
+
],
|
|
33
|
+
topic_labels = {
|
|
34
|
+
cc = local.common_vars.locals.cost_center
|
|
35
|
+
}
|
|
36
|
+
subscription_labels = {
|
|
37
|
+
cc = local.common_vars.locals.cost_center
|
|
38
|
+
}
|
|
39
|
+
grant_token_creator = false,
|
|
40
|
+
}
|
|
41
|
+
)
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
<% if (pushOrPull == 'push') { %>push_subscriptions:
|
|
2
2
|
- name: "<%-existingTopic%>+<%-subscriberName%>"
|
|
3
|
-
push_endpoint: "<%-pushEndpoint%>"
|
|
3
|
+
push_endpoint: "<%-pushEndpoint%>" <% if (env == 'prod') { %>
|
|
4
|
+
dead_letter_topic: "<%-dlqTopic%>" <% } %>
|
|
4
5
|
oidc_service_account_email: "<%-oidcEmail%>"
|
|
5
6
|
audience: "<%-audience%>"
|
|
6
7
|
expiration_policy: ""<% } %><% if (pushOrPull == 'pull') { %>pull_subscriptions:
|
|
7
8
|
- name: "<%-existingTopic%>+<%-subscriberName%>"
|
|
8
|
-
ack_deadline_seconds: "60"
|
|
9
|
+
ack_deadline_seconds: "60" <% if (env == 'prod') { %>
|
|
10
|
+
dead_letter_topic: "<%-dlqTopic%>" <% } %>
|
|
9
11
|
expiration_policy: ""<% } %>
|
|
@@ -50,6 +50,11 @@ module.exports = class extends BaseGenerator {
|
|
|
50
50
|
name: 'ddl',
|
|
51
51
|
message: 'Please provide an optional list of DDL statements to run inside the newly created database. Leave empty to add them later.',
|
|
52
52
|
},
|
|
53
|
+
{
|
|
54
|
+
type: 'input',
|
|
55
|
+
name: 'versionRetentionPeriod',
|
|
56
|
+
message: 'Please provide version retention period. Maximum value 7d, possible values include 84000s, 1h, 2d. Leave empty for default value 1h.',
|
|
57
|
+
},
|
|
53
58
|
];
|
|
54
59
|
|
|
55
60
|
return this.prompt(prompts).then((props) => {
|
|
@@ -64,6 +69,7 @@ module.exports = class extends BaseGenerator {
|
|
|
64
69
|
instanceAllocation,
|
|
65
70
|
databaseName,
|
|
66
71
|
ddl,
|
|
72
|
+
versionRetentionPeriod,
|
|
67
73
|
} = this.answers;
|
|
68
74
|
|
|
69
75
|
['prod', 'staging'].forEach((env) => {
|
|
@@ -78,6 +84,7 @@ module.exports = class extends BaseGenerator {
|
|
|
78
84
|
instanceAllocation,
|
|
79
85
|
databaseName,
|
|
80
86
|
ddl,
|
|
87
|
+
versionRetentionPeriod,
|
|
81
88
|
},
|
|
82
89
|
);
|
|
83
90
|
});
|
|
@@ -17,4 +17,8 @@ locals {
|
|
|
17
17
|
# The number of processing units allocated to this instance.
|
|
18
18
|
# At most one of either num_nodes or processing_units can be present in terraform.
|
|
19
19
|
processing_units = "<%-processingUnits%>" <% } %>
|
|
20
|
+
# The time frame it will be possible to restore the database to a point in time.
|
|
21
|
+
# Values from 1h up to max 7d
|
|
22
|
+
<% if (versionRetentionPeriod !== '') { %>
|
|
23
|
+
version_retention_period = "<%-versionRetentionPeriod%>" <% } %>
|
|
20
24
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Terragrunt will copy the Terraform configurations specified by the source parameter, along with any files in the
|
|
2
2
|
# working directory, into a temporary folder, and execute your Terraform commands in that folder.
|
|
3
3
|
terraform {
|
|
4
|
-
source = "git::https://github.com/extenda/tf-module-gcp-spanner//?ref=v0.1.
|
|
4
|
+
source = "git::https://github.com/extenda/tf-module-gcp-spanner//?ref=v0.1.1"
|
|
5
5
|
}
|
|
6
6
|
|
|
7
7
|
# Include all settings from the root terragrunt.hcl file
|