@hiiretail/gcp-infra-cli 0.62.4 → 0.65.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.
@@ -5,7 +5,11 @@ locals {
5
5
  clan_name = "<%-clan%>"
6
6
  region = "europe-west1"
7
7
  clan_group_email = "tribe-<%-tribe%>-<%-clan%>@extendaretail.com"
8
- clan_slack_channels = ["#<%-tribe%>-<%-clan%>-monitor"]
8
+ clan_slack_channels = [
9
+ {
10
+ name = "#<%-tribe%>-<%-clan%>-monitor"
11
+ }
12
+ ]
9
13
  project_id_slack_token = "tf-admin-90301274"
10
14
  cost_center = "<%-costCenter%>"
11
15
  }
@@ -42,6 +42,13 @@ module.exports = class extends BaseGenerator {
42
42
  store: true,
43
43
  default: 10,
44
44
  },
45
+ {
46
+ type: 'list',
47
+ name: 'enableBackups',
48
+ message: 'Enable Databases backup?',
49
+ default: true,
50
+ choices: [true, false],
51
+ },
45
52
  ];
46
53
 
47
54
  return this.prompt(prompts).then((props) => {
@@ -12,7 +12,7 @@ include {
12
12
  dependency "notification_channels" {
13
13
  config_path = "../notification-channels"
14
14
  mock_outputs = {
15
- notification_channel_name = ["dummy-channel"]
15
+ notification_channels = ["dummy-channel"]
16
16
  }
17
17
  }
18
18
 
@@ -25,7 +25,7 @@ locals {
25
25
  inputs = merge(local.project_vars.locals, local.common_vars.locals,
26
26
  {
27
27
  clan_project_id = local.project_vars.locals.project_id
28
- notification_channels = dependency.notification_channels.outputs.notification_channel_name
28
+ notification_channels = dependency.notification_channels.outputs.notification_channels
29
29
  cloudsql_monitoring = true
30
30
  user_labels = {
31
31
  cc = local.common_vars.locals.cost_center
@@ -64,4 +64,13 @@ locals {
64
64
  #Type: String
65
65
  #Default: "PD_SSD"
66
66
  # disk_type = "PD_SSD"
67
+
68
+ #Description: The database backup configuration.
69
+ #Type: Map
70
+ backup_configuration = {
71
+ enabled = <%- enableBackups %>
72
+ binary_log_enabled = enabled
73
+ start_time = "04:00"
74
+ point_in_time_recovery_enabled = true
75
+ }
67
76
  }
@@ -60,4 +60,14 @@ locals {
60
60
  #Type: String
61
61
  #Default: "PD_SSD"
62
62
  # disk_type = "PD_SSD"
63
+
64
+ #Description: The database backup configuration.
65
+ #Type: Map
66
+ #Default: missing
67
+ backup_configuration = {
68
+ enabled = <%- enableBackups %>
69
+ binary_log_enabled = true
70
+ start_time = "04:00"
71
+ location = "europe-west1"
72
+ }
63
73
  }
@@ -60,4 +60,14 @@ locals {
60
60
  #Type: String
61
61
  #Default: "PD_SSD"
62
62
  # disk_type = "PD_SSD"
63
+
64
+ #Description: The database backup configuration.
65
+ #Type: Map
66
+ #Default: missing
67
+ backup_configuration = {
68
+ enabled = <%- enableBackups %>
69
+ start_time = "04:00"
70
+ location = "europe-west1"
71
+ point_in_time_recovery_enabled = true
72
+ }
63
73
  }
@@ -12,7 +12,7 @@ include {
12
12
  dependency "notification_channels" {
13
13
  config_path = "../notification-channels"
14
14
  mock_outputs = {
15
- notification_channel_name = ["dummy-channel"]
15
+ notification_channels = ["dummy-channel"]
16
16
  }
17
17
  }
18
18
 
@@ -25,7 +25,7 @@ locals {
25
25
  inputs = merge(local.project_vars.locals, local.common_vars.locals,
26
26
  {
27
27
  clan_project_id = local.project_vars.locals.project_id
28
- notification_channels = dependency.notification_channels.outputs.notification_channel_name
28
+ notification_channels = dependency.notification_channels.outputs.notification_channels
29
29
  firestore_monitoring = true
30
30
  user_labels = {
31
31
  cc = local.common_vars.locals.cost_center
@@ -12,7 +12,7 @@ include {
12
12
  dependency "notification_channels" {
13
13
  config_path = "../notification-channels"
14
14
  mock_outputs = {
15
- notification_channel_name = ["dummy-channel"]
15
+ notification_channels = ["dummy-channel"]
16
16
  }
17
17
  }
18
18
 
@@ -25,7 +25,7 @@ locals {
25
25
  inputs = merge(local.project_vars.locals, local.common_vars.locals,
26
26
  {
27
27
  clan_project_id = local.project_vars.locals.project_id
28
- notification_channels = dependency.notification_channels.outputs.notification_channel_name
28
+ notification_channels = dependency.notification_channels.outputs.notification_channels
29
29
  memorystore_monitoring = true
30
30
  user_labels = {
31
31
  cc = local.common_vars.locals.cost_center
@@ -12,7 +12,7 @@ include {
12
12
  dependency "notification_channels" {
13
13
  config_path = "../notification-channels"
14
14
  mock_outputs = {
15
- notification_channel_name = ["dummy-channel"]
15
+ notification_channels = ["dummy-channel"]
16
16
  }
17
17
  }
18
18
 
@@ -25,7 +25,7 @@ locals {
25
25
  inputs = merge(local.project_vars.locals, local.common_vars.locals,
26
26
  {
27
27
  clan_project_id = local.project_vars.locals.project_id
28
- notification_channels = dependency.notification_channels.outputs.notification_channel_name
28
+ notification_channels = dependency.notification_channels.outputs.notification_channels
29
29
  cloudfunction_monitoring = true
30
30
  user_labels = {
31
31
  cc = local.common_vars.locals.cost_center
@@ -12,7 +12,7 @@ include {
12
12
  dependency "notification_channels" {
13
13
  config_path = "../notification-channels"
14
14
  mock_outputs = {
15
- notification_channel_name = ["dummy-channel"]
15
+ notification_channels = ["dummy-channel"]
16
16
  }
17
17
  }
18
18
 
@@ -25,7 +25,7 @@ locals {
25
25
  inputs = merge(local.project_vars.locals, local.common_vars.locals,
26
26
  {
27
27
  clan_project_id = local.project_vars.locals.project_id
28
- notification_channels = dependency.notification_channels.outputs.notification_channel_name
28
+ notification_channels = dependency.notification_channels.outputs.notification_channels
29
29
  cloudrun_monitoring = true
30
30
  user_labels = {
31
31
  cc = local.common_vars.locals.cost_center
@@ -12,7 +12,7 @@ include {
12
12
  dependency "notification_channels" {
13
13
  config_path = "../notification-channels"
14
14
  mock_outputs = {
15
- notification_channel_name = ["dummy-channel"]
15
+ notification_channels = ["dummy-channel"]
16
16
  }
17
17
  }
18
18
 
@@ -25,7 +25,7 @@ locals {
25
25
  inputs = merge(local.project_vars.locals, local.common_vars.locals,
26
26
  {
27
27
  clan_project_id = local.project_vars.locals.project_id
28
- notification_channels = dependency.notification_channels.outputs.notification_channel_name
28
+ notification_channels = dependency.notification_channels.outputs.notification_channels
29
29
  dataflow_monitoring = true
30
30
  user_labels = {
31
31
  cc = local.common_vars.locals.cost_center
@@ -7,6 +7,7 @@ const {
7
7
  validSystemName,
8
8
  validVersion,
9
9
  validSubscriberName,
10
+ checkExistingTopicPath,
10
11
  } = require('./validate');
11
12
  const handleSubscribers = require('./handle-subscribers');
12
13
  const { getProjectId, getProdPushEndopint } = require('./get-gcp-projects');
@@ -117,7 +118,7 @@ module.exports = class extends BaseGenerator {
117
118
  type: 'input',
118
119
  name: 'existingTopic',
119
120
  message: 'Please provide the name of the existing topic you want to subscribe to',
120
- validate: required,
121
+ validate: (input) => required(input) && checkExistingTopicPath(input),
121
122
  },
122
123
  {
123
124
  when: (response) => response.createResource === 'subscription' && response.pushOrPull === 'push',
@@ -12,7 +12,7 @@ include {
12
12
  dependency "notification_channels" {
13
13
  config_path = "../notification-channels"
14
14
  mock_outputs = {
15
- notification_channel_name = ["dummy-channel"]
15
+ notification_channels = ["dummy-channel"]
16
16
  }
17
17
  }
18
18
 
@@ -25,7 +25,7 @@ locals {
25
25
  inputs = merge(local.project_vars.locals, local.common_vars.locals,
26
26
  {
27
27
  clan_project_id = local.project_vars.locals.project_id
28
- notification_channels = dependency.notification_channels.outputs.notification_channel_name
28
+ notification_channels = dependency.notification_channels.outputs.notification_channels
29
29
  pubsub_monitoring = true
30
30
  user_labels = {
31
31
  cc = local.common_vars.locals.cost_center
@@ -1,3 +1,6 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+
1
4
  const validSystemName = (input) => {
2
5
  if (input.replace(/\s/g, '').length === 3) {
3
6
  return true;
@@ -24,9 +27,18 @@ const validSubscriberName = (input) => {
24
27
  return 'Not supported input for subscriber name';
25
28
  };
26
29
 
30
+ const checkExistingTopicPath = (input) => {
31
+ const topicDirPath = path.join(process.cwd(), 'infra', 'staging', 'pubsub', input);
32
+
33
+ if (fs.existsSync(topicDirPath)) {
34
+ return true;
35
+ }
36
+ return 'Topic does not exist. Check the spelling';
37
+ };
27
38
 
28
39
  module.exports = {
29
40
  validSystemName,
30
41
  validVersion,
31
42
  validSubscriberName,
43
+ checkExistingTopicPath,
32
44
  };
@@ -0,0 +1,4 @@
1
+ {
2
+ "name": "Spanner",
3
+ "description": "Create Cloud Spanner resources"
4
+ }
@@ -0,0 +1,91 @@
1
+ const path = require('path');
2
+ const chalk = require('chalk');
3
+ const BaseGenerator = require('../../../src/BaseGenerator');
4
+ const { required } = require('../../../src/validators');
5
+
6
+ module.exports = class extends BaseGenerator {
7
+ prompting() {
8
+ const prompts = [
9
+ {
10
+ type: 'input',
11
+ name: 'instanceName',
12
+ message: 'Please provide a name for the instance. The name must be between 6 and 30 characters in length',
13
+ validate: required,
14
+ },
15
+ {
16
+ type: 'input',
17
+ name: 'displayName',
18
+ message: 'Please provide the descriptive name for this instance. Unique per project and between 4 and 30 characters in length',
19
+ validate: required,
20
+ },
21
+ {
22
+ type: 'list',
23
+ name: 'instanceAllocation',
24
+ 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',
25
+ default: 'processing_units',
26
+ choices: ['processing_units', 'num_nodes'],
27
+ },
28
+ {
29
+ when: (response) => response.instanceAllocation === 'processing_units',
30
+ type: 'input',
31
+ name: 'processingUnits',
32
+ message: 'Please provide the number of processing units allocated to the instance',
33
+ validate: required,
34
+ },
35
+ {
36
+ when: (response) => response.instanceAllocation === 'num_nodes',
37
+ type: 'input',
38
+ name: 'numNodes',
39
+ message: 'Please provide the number of nodes allocated to the instance',
40
+ validate: required,
41
+ },
42
+ {
43
+ type: 'input',
44
+ name: 'databaseName',
45
+ message: 'Please provide a name for the database',
46
+ validate: required,
47
+ },
48
+ {
49
+ type: 'input',
50
+ name: 'ddl',
51
+ message: 'Please provide an optional list of DDL statements to run inside the newly created database. Leave empty to add them later.',
52
+ },
53
+ ];
54
+
55
+ return this.prompt(prompts).then((props) => {
56
+ this.answers = props;
57
+ });
58
+ }
59
+
60
+ writing() {
61
+ const {
62
+ instanceName,
63
+ displayName,
64
+ instanceAllocation,
65
+ databaseName,
66
+ ddl,
67
+ } = this.answers;
68
+
69
+ ['prod', 'staging'].forEach((env) => {
70
+ this.copyDir(
71
+ 'spanner',
72
+ path.join('infra', env, 'spanner'),
73
+ {
74
+ ...this.answers,
75
+ env,
76
+ instanceName,
77
+ displayName,
78
+ instanceAllocation,
79
+ databaseName,
80
+ ddl,
81
+ },
82
+ );
83
+ });
84
+ }
85
+
86
+ end() {
87
+ this.log(`
88
+ ${chalk.green('Your Cloud Spanner resources have now been created. Please add any other specifications supported by the module if needed')}
89
+ ${chalk.green('1.')} Push this change in a feature branch and open a pull request.`);
90
+ }
91
+ };
@@ -0,0 +1,4 @@
1
+ databases:
2
+ - name: "<%-databaseName%>" <% if (ddl == '') { %><% } else { %>
3
+ ddl:
4
+ - "<%-ddl%>" <% } %>
@@ -0,0 +1,20 @@
1
+ locals {
2
+ # A unique identifier for the instance, which cannot be changed after the instance is created.
3
+ # The name must be between 6 and 30 characters in length.
4
+ instance_name = "<%-instanceName%>"
5
+
6
+ # The name of the instance's configuration which defines the geographic placement and replication of your databases in this instance.
7
+ # It determines where your data is stored.
8
+ <% if (env == 'staging') { %>
9
+ instance_config = "regional-europe-west1" <% } else { %>
10
+ instance_config = "eur3" <% } %>
11
+
12
+ display_name = "<%-displayName%>"
13
+ <% if (instanceAllocation == 'num_nodes') { %>
14
+ # The number of nodes allocated to this instance.
15
+ # At most one of either num_nodes or processing_units can be present in terraform.
16
+ num_nodes = "<%-numNodes%>" <% } %><% if (instanceAllocation == 'processing_units') { %>
17
+ # The number of processing units allocated to this instance.
18
+ # At most one of either num_nodes or processing_units can be present in terraform.
19
+ processing_units = "<%-processingUnits%>" <% } %>
20
+ }
@@ -0,0 +1,30 @@
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/extenda/tf-module-gcp-spanner//?ref=v0.1.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
+ spec_vars = read_terragrunt_config("${get_terragrunt_dir()}/spec.hcl")
14
+ project_vars = read_terragrunt_config(find_in_parent_folders("project.hcl"))
15
+ common_vars = read_terragrunt_config(find_in_parent_folders("common.hcl"))
16
+ }
17
+
18
+ # These are the variables we have to pass in to use the module specified in the terragrunt configuration above
19
+ inputs = merge(
20
+ yamldecode(
21
+ file("${get_terragrunt_dir()}/databases.yaml")),
22
+ local.spec_vars.locals,
23
+ local.project_vars.locals,
24
+ {
25
+ instance_labels = {
26
+ cc = local.common_vars.locals.cost_center
27
+ "created" = "terraform"
28
+ }
29
+ }
30
+ )
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hiiretail/gcp-infra-cli",
3
- "version": "0.62.4",
3
+ "version": "0.65.0",
4
4
  "description": "Infrastructure as code generator for GCP.",
5
5
  "main": "src/cli.js",
6
6
  "bin": {