@hiiretail/gcp-infra-cli 0.76.0 → 0.76.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/monitoring/handle-yaml.js +28 -0
- package/generators/resources/monitoring/index.js +49 -111
- package/generators/resources/monitoring/templates/alerts/terragrunt.hcl +4 -3
- package/generators/resources/monitoring/templates/slos/slos.yaml +25 -19
- package/generators/resources/monitoring/templates/slos/terragrunt.hcl +2 -14
- package/generators/resources/monitoring/templates/uptime-checks/terragrunt.hcl +7 -5
- package/generators/resources/monitoring/templates/uptime-checks/uptime-checks.yaml +3 -3
- package/generators/resources/monitoring/validate.js +10 -14
- package/package.json +1 -1
- package/generators/resources/monitoring/append.js +0 -105
- package/generators/resources/monitoring/handle-alerts.js +0 -11
- package/generators/resources/monitoring/handle-slos.js +0 -28
- package/generators/resources/monitoring/handle-uptime.js +0 -28
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
const ejs = require('ejs');
|
|
2
|
+
|
|
3
|
+
const handleAlerts = (alerts, templates, answers) => {
|
|
4
|
+
const template = templates[`${answers.alertResource}`][`${answers.alert}`];
|
|
5
|
+
const newAlert = JSON.parse(ejs.render(JSON.stringify(template), answers));
|
|
6
|
+
|
|
7
|
+
alerts.push(newAlert);
|
|
8
|
+
return alerts;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const handleSlos = (slos, templates, answers) => {
|
|
12
|
+
const template = templates[`${answers.sli}`];
|
|
13
|
+
const newSLO = JSON.parse(ejs.render(JSON.stringify(template), answers));
|
|
14
|
+
|
|
15
|
+
if (answers.burnRateAlert === 'no') newSLO.alert = {};
|
|
16
|
+
|
|
17
|
+
slos.push(newSLO);
|
|
18
|
+
return slos;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const handleUptimeChecks = (slos, templates, answers) => {
|
|
22
|
+
const newCheck = JSON.parse(ejs.render(JSON.stringify(templates), answers));
|
|
23
|
+
|
|
24
|
+
slos.push(newCheck);
|
|
25
|
+
return slos;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
module.exports = { handleAlerts, handleSlos, handleUptimeChecks };
|
|
@@ -4,12 +4,12 @@ const fs = require('fs');
|
|
|
4
4
|
const yaml = require('js-yaml');
|
|
5
5
|
const BaseGenerator = require('../../../src/BaseGenerator');
|
|
6
6
|
const { required } = require('../../../src/validators');
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const handleUptimeFile = require('./handle-uptime');
|
|
10
|
-
const handleAlerts = require('./handle-alerts');
|
|
7
|
+
const validate = require('./validate');
|
|
8
|
+
const { handleSlos, handleAlerts, handleUptimeChecks } = require('./handle-yaml');
|
|
11
9
|
|
|
10
|
+
const uptimeCheckTemplates = yaml.load(fs.readFileSync(`${__dirname}/templates/uptime-checks/uptime-checks.yaml`));
|
|
12
11
|
const alertTemplates = yaml.load(fs.readFileSync(`${__dirname}/templates/alerts/alerts.yaml`));
|
|
12
|
+
const sloTemplates = yaml.load(fs.readFileSync(`${__dirname}/templates/slos/slos.yaml`));
|
|
13
13
|
|
|
14
14
|
module.exports = class extends BaseGenerator {
|
|
15
15
|
async prompting() {
|
|
@@ -37,7 +37,7 @@ module.exports = class extends BaseGenerator {
|
|
|
37
37
|
type: 'input',
|
|
38
38
|
name: 'systemName',
|
|
39
39
|
message: 'Please provide three-letter system name as defined in Styra (example: sre, ptf, sda, che, pnp, iam...)',
|
|
40
|
-
validate: required &&
|
|
40
|
+
validate: required && validate.systemName,
|
|
41
41
|
},
|
|
42
42
|
{
|
|
43
43
|
when: (response) => ['slos', 'uptime-checks'].includes(response.monitoringResource) || response.alertResource === 'cloud_run',
|
|
@@ -51,7 +51,7 @@ module.exports = class extends BaseGenerator {
|
|
|
51
51
|
type: 'input',
|
|
52
52
|
name: 'runbookLink',
|
|
53
53
|
message: 'Please provide the full URL to your runbook in confluence (Leave empty if none)',
|
|
54
|
-
validate: required &&
|
|
54
|
+
validate: required && validate.url,
|
|
55
55
|
},
|
|
56
56
|
{
|
|
57
57
|
when: (response) => response.alertResource === 'cloud_scheduler',
|
|
@@ -65,28 +65,28 @@ module.exports = class extends BaseGenerator {
|
|
|
65
65
|
type: 'input',
|
|
66
66
|
name: 'databaseId',
|
|
67
67
|
message: 'Please provide the "database id"',
|
|
68
|
-
validate: required &&
|
|
68
|
+
validate: required && validate.databaseId,
|
|
69
69
|
},
|
|
70
70
|
{
|
|
71
71
|
when: (response) => response.alertResource === 'memorystore',
|
|
72
72
|
type: 'input',
|
|
73
73
|
name: 'instanceId',
|
|
74
74
|
message: 'Please provide the "instance id"',
|
|
75
|
-
validate: required &&
|
|
75
|
+
validate: required && validate.instanceID,
|
|
76
76
|
},
|
|
77
77
|
{
|
|
78
78
|
when: (response) => response.alertResource === 'pub_sub',
|
|
79
79
|
type: 'input',
|
|
80
80
|
name: 'subscriptionId',
|
|
81
81
|
message: 'Please provide the "subscription id"',
|
|
82
|
-
validate: required &&
|
|
82
|
+
validate: required && validate.pubSubSubscription,
|
|
83
83
|
},
|
|
84
84
|
{
|
|
85
85
|
when: (response) => response.monitoringResource === 'uptime-checks',
|
|
86
86
|
type: 'input',
|
|
87
87
|
name: 'hostname',
|
|
88
88
|
message: 'Please provide the base hostname of the service (example: my-service.retailsvc.com)',
|
|
89
|
-
validate: required &&
|
|
89
|
+
validate: required && validate.hostName,
|
|
90
90
|
},
|
|
91
91
|
{
|
|
92
92
|
when: (response) => response.monitoringResource === 'uptime-checks',
|
|
@@ -101,132 +101,70 @@ module.exports = class extends BaseGenerator {
|
|
|
101
101
|
type: 'list',
|
|
102
102
|
name: 'sli',
|
|
103
103
|
message: 'Please select the SLI',
|
|
104
|
-
choices:
|
|
104
|
+
choices: Object.keys(sloTemplates),
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
when: (response) => response.monitoringResource === 'slos' && response.sli === 'availability',
|
|
108
|
+
type: 'input',
|
|
109
|
+
name: 'uptimeCheckId',
|
|
110
|
+
message: 'Please provide the "Uptime Check ID" (NOTE: The "Uptime check" needs to have been created first in order to fetch the ID)',
|
|
111
|
+
validate: required,
|
|
105
112
|
},
|
|
106
113
|
{
|
|
107
114
|
when: (response) => response.monitoringResource === 'slos',
|
|
108
115
|
type: 'list',
|
|
109
|
-
name: '
|
|
116
|
+
name: 'burnRateAlert',
|
|
110
117
|
message: 'Please select yes if you want to have burn-rate alerts included',
|
|
111
118
|
default: 'yes',
|
|
112
119
|
choices: ['yes', 'no'],
|
|
113
120
|
},
|
|
114
|
-
{
|
|
115
|
-
when: (response) => response.monitoringResource === 'slos' && response.sli === 'availability',
|
|
116
|
-
type: 'confirm',
|
|
117
|
-
name: 'info',
|
|
118
|
-
message: 'WARNING: Make sure an uptime check has been created BEFORE continuing with the creation of this SLO.',
|
|
119
|
-
},
|
|
120
121
|
]);
|
|
121
122
|
}
|
|
122
123
|
|
|
123
124
|
async writing() {
|
|
124
|
-
const {
|
|
125
|
-
|
|
126
|
-
serviceName,
|
|
127
|
-
hostname,
|
|
128
|
-
sli,
|
|
129
|
-
systemName,
|
|
130
|
-
burnRateAlerts,
|
|
131
|
-
} = this.answers;
|
|
125
|
+
const { monitoringResource, serviceName } = this.answers;
|
|
126
|
+
const resourceDir = path.join(process.cwd(), 'infra', 'prod', 'monitoring', monitoringResource);
|
|
132
127
|
|
|
133
|
-
const
|
|
128
|
+
const copyTemplate = (resource, resourcePath, yamlPath) => {
|
|
129
|
+
if (!fs.existsSync(resourcePath)) fs.mkdirSync(resourcePath, { recursive: true });
|
|
130
|
+
if (!fs.existsSync(yamlPath)) fs.writeFileSync(yamlPath, '');
|
|
131
|
+
if (!fs.existsSync(`${path}/terragrunt.hcl`)) {
|
|
132
|
+
this.fs.copyTpl(
|
|
133
|
+
this.templatePath(`${resource}/terragrunt.hcl`),
|
|
134
|
+
this.destinationPath(`${resourcePath}/terragrunt.hcl`),
|
|
135
|
+
this.answers,
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
};
|
|
134
139
|
|
|
135
140
|
if (monitoringResource === 'uptime-checks') {
|
|
136
|
-
|
|
137
|
-
fs.mkdirSync(resourcePath, { recursive: true });
|
|
138
|
-
}
|
|
141
|
+
const yamlPath = `${resourceDir}/uptime-checks.yaml`;
|
|
139
142
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
...this.answers,
|
|
147
|
-
serviceName,
|
|
148
|
-
hostname,
|
|
149
|
-
systemName,
|
|
150
|
-
},
|
|
151
|
-
);
|
|
152
|
-
} else {
|
|
153
|
-
await handleUptimeFile(this.answers, uptimeYamlFile);
|
|
154
|
-
}
|
|
143
|
+
copyTemplate('uptime-checks', resourceDir, yamlPath);
|
|
144
|
+
|
|
145
|
+
const oldYaml = yaml.load(fs.readFileSync(yamlPath, 'utf8')) || [];
|
|
146
|
+
const newYaml = await handleUptimeChecks(oldYaml, uptimeCheckTemplates, this.answers);
|
|
147
|
+
|
|
148
|
+
fs.writeFileSync(yamlPath, yaml.dump(newYaml));
|
|
155
149
|
}
|
|
156
150
|
|
|
157
151
|
if (monitoringResource === 'slos') {
|
|
158
|
-
const
|
|
159
|
-
const
|
|
160
|
-
const
|
|
161
|
-
const contents = fs.readFileSync(fileName, 'utf-8');
|
|
162
|
-
const result = contents.includes(str);
|
|
163
|
-
return result;
|
|
164
|
-
};
|
|
165
|
-
|
|
166
|
-
if (!fs.existsSync(serviceDir)) {
|
|
167
|
-
fs.mkdirSync(serviceDir, { recursive: true });
|
|
168
|
-
}
|
|
152
|
+
const service = serviceName.replace(/ /g, '-').toLowerCase();
|
|
153
|
+
const servicePath = path.join(process.cwd(), 'infra', 'prod', 'monitoring', monitoringResource, service);
|
|
154
|
+
const yamlPath = `${servicePath}/slos.yaml`;
|
|
169
155
|
|
|
170
|
-
|
|
171
|
-
if (fileContainsFilter(`${serviceDir}/terragrunt.hcl`, 'metric_filter') === false) {
|
|
172
|
-
this.fs.copyTpl(
|
|
173
|
-
this.templatePath('slos/terragrunt.hcl'),
|
|
174
|
-
this.destinationPath(`${serviceDir}/terragrunt.hcl`),
|
|
175
|
-
{
|
|
176
|
-
...this.answers,
|
|
177
|
-
monitoringResource,
|
|
178
|
-
serviceName,
|
|
179
|
-
systemName,
|
|
180
|
-
burnRateAlerts,
|
|
181
|
-
},
|
|
182
|
-
);
|
|
183
|
-
}
|
|
184
|
-
} else {
|
|
185
|
-
this.fs.copyTpl(
|
|
186
|
-
this.templatePath('slos/terragrunt.hcl'),
|
|
187
|
-
this.destinationPath(`${serviceDir}/terragrunt.hcl`),
|
|
188
|
-
{
|
|
189
|
-
...this.answers,
|
|
190
|
-
monitoringResource,
|
|
191
|
-
serviceName,
|
|
192
|
-
systemName,
|
|
193
|
-
burnRateAlerts,
|
|
194
|
-
},
|
|
195
|
-
);
|
|
196
|
-
}
|
|
156
|
+
copyTemplate('slos', servicePath, yamlPath);
|
|
197
157
|
|
|
198
|
-
const
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
this.destinationPath(sloYamlFile),
|
|
203
|
-
{
|
|
204
|
-
...this.answers,
|
|
205
|
-
monitoringResource,
|
|
206
|
-
serviceName,
|
|
207
|
-
systemName,
|
|
208
|
-
sli,
|
|
209
|
-
burnRateAlerts,
|
|
210
|
-
},
|
|
211
|
-
);
|
|
212
|
-
} else {
|
|
213
|
-
await handleSlosFile(this.answers, sloYamlFile);
|
|
214
|
-
}
|
|
158
|
+
const oldYaml = yaml.load(fs.readFileSync(yamlPath, 'utf8')) || [];
|
|
159
|
+
const newYaml = await handleSlos(oldYaml, sloTemplates, this.answers);
|
|
160
|
+
|
|
161
|
+
fs.writeFileSync(yamlPath, yaml.dump(newYaml));
|
|
215
162
|
}
|
|
216
163
|
|
|
217
164
|
if (monitoringResource === 'alerts') {
|
|
218
|
-
const yamlPath = `${
|
|
219
|
-
const terraPath = `${resourcePath}/terragrunt.hcl`;
|
|
220
|
-
if (!fs.existsSync(resourcePath)) fs.mkdirSync(resourcePath, { recursive: true });
|
|
221
|
-
if (!fs.existsSync(yamlPath)) fs.writeFileSync(yamlPath, '');
|
|
165
|
+
const yamlPath = `${resourceDir}/alerts.yaml`;
|
|
222
166
|
|
|
223
|
-
|
|
224
|
-
this.fs.copyTpl(
|
|
225
|
-
this.templatePath('alerts/terragrunt.hcl'),
|
|
226
|
-
this.destinationPath(terraPath),
|
|
227
|
-
this.answers,
|
|
228
|
-
);
|
|
229
|
-
}
|
|
167
|
+
copyTemplate('alerts', resourceDir, yamlPath);
|
|
230
168
|
|
|
231
169
|
const oldYaml = yaml.load(fs.readFileSync(yamlPath, 'utf8')) || [];
|
|
232
170
|
const newYaml = await handleAlerts(oldYaml, alertTemplates, this.answers);
|
|
@@ -23,11 +23,12 @@ locals {
|
|
|
23
23
|
|
|
24
24
|
# These are the variables we have to pass in to use the module specified in the terragrunt configuration above
|
|
25
25
|
inputs = {
|
|
26
|
-
monitoring_project_id = local.project_vars.locals
|
|
26
|
+
monitoring_project_id = lookup(local.project_vars.locals, "monitoring_project_id", local.project_vars.locals.tribe_project_id),
|
|
27
27
|
notification_channels = dependency.notification_channels.outputs.notification_channels,
|
|
28
28
|
policies = yamldecode(file("${get_terragrunt_dir()}/alerts.yaml")),
|
|
29
29
|
user_labels = {
|
|
30
|
-
cc
|
|
31
|
-
clan
|
|
30
|
+
cc = local.common_vars.locals.cost_center
|
|
31
|
+
clan = local.common_vars.locals.clan_name
|
|
32
|
+
jira_project_key = lookup(local.project_vars.locals, "jira_project_key", null)
|
|
32
33
|
},
|
|
33
34
|
}
|
|
@@ -1,35 +1,41 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
goal: 0.95
|
|
4
|
-
calendar_period: MONTH
|
|
5
|
-
type: request_based_sli
|
|
6
|
-
method: distribution_cut
|
|
7
|
-
metric_filter: |-
|
|
8
|
-
metric.type="knative.dev/serving/revision/request_latencies"
|
|
9
|
-
resource.type="knative_revision"
|
|
10
|
-
resource.labels.service_name="<%-serviceName%>"
|
|
11
|
-
range_min: 0
|
|
12
|
-
range_max: 100<% if (burnRateAlerts === 'no') { %>
|
|
13
|
-
alert: {}<% } %><% } %><% if (sli === 'availability') { %>- display_name: Month - Availability
|
|
1
|
+
availability:
|
|
2
|
+
display_name: Month - Availability
|
|
14
3
|
slo_id: month-availability
|
|
15
4
|
goal: 0.998
|
|
16
5
|
calendar_period: MONTH
|
|
17
6
|
type: windows_based_sli
|
|
18
7
|
method: boolean_filter
|
|
19
|
-
window_period: 60s
|
|
20
|
-
|
|
8
|
+
window_period: 60s
|
|
9
|
+
metric_filter: |
|
|
10
|
+
metric.type="monitoring.googleapis.com/uptime_check/check_passed"
|
|
11
|
+
resource.type="uptime_url"
|
|
12
|
+
metric.labels.check_id="<%-uptimeCheckId%>"
|
|
13
|
+
error-rate:
|
|
14
|
+
display_name: Month - Error rate
|
|
21
15
|
slo_id: month-error-rate
|
|
22
16
|
goal: 0.999
|
|
23
17
|
calendar_period: MONTH
|
|
24
18
|
type: request_based_sli
|
|
25
19
|
method: good_total_ratio
|
|
26
|
-
bad_service_filter:
|
|
20
|
+
bad_service_filter: |
|
|
27
21
|
metric.type="knative.dev/serving/revision/request_count"
|
|
28
22
|
resource.type="knative_revision"
|
|
29
23
|
metric.labels.response_code_class="5xx"
|
|
30
24
|
resource.labels.service_name="<%-serviceName%>"
|
|
31
|
-
total_service_filter:
|
|
25
|
+
total_service_filter: |
|
|
32
26
|
metric.type="knative.dev/serving/revision/request_count"
|
|
33
27
|
resource.type="knative_revision"
|
|
34
|
-
resource.labels.service_name="<%-serviceName%>"
|
|
35
|
-
|
|
28
|
+
resource.labels.service_name="<%-serviceName%>"
|
|
29
|
+
latency:
|
|
30
|
+
display_name: Month - Latency
|
|
31
|
+
slo_id: month-latency
|
|
32
|
+
goal: 0.95
|
|
33
|
+
calendar_period: MONTH
|
|
34
|
+
type: request_based_sli
|
|
35
|
+
method: distribution_cut
|
|
36
|
+
range_min: 0
|
|
37
|
+
range_max: 100
|
|
38
|
+
metric_filter: |
|
|
39
|
+
metric.type="knative.dev/serving/revision/request_latencies"
|
|
40
|
+
resource.type="knative_revision"
|
|
41
|
+
resource.labels.service_name="<%-serviceName%>"
|
|
@@ -9,13 +9,6 @@ include {
|
|
|
9
9
|
path = find_in_parent_folders("terragrunt_root.hcl")
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
dependency "uptimecheck_id" {
|
|
13
|
-
config_path = "../../uptime-checks"
|
|
14
|
-
mock_outputs = {
|
|
15
|
-
uptime_check_ids = ["dummy-id"]
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
12
|
locals {
|
|
20
13
|
project_vars = read_terragrunt_config(find_in_parent_folders("project.hcl"))
|
|
21
14
|
}
|
|
@@ -25,13 +18,8 @@ inputs = merge(
|
|
|
25
18
|
local.project_vars.locals,
|
|
26
19
|
{
|
|
27
20
|
service_name = "<%-systemName%>.<%-serviceName%>"
|
|
21
|
+
monitoring_project_id = lookup(local.project_vars.locals, "monitoring_project_id", local.project_vars.locals.tribe_project_id),
|
|
28
22
|
slos = yamldecode(file("${get_terragrunt_dir()}/slos.yaml")),
|
|
29
|
-
telemetry_resource_name = "//container.googleapis.com/projects/${local.project_vars.locals.
|
|
30
|
-
<% if (sli === 'availability') { %>
|
|
31
|
-
metric_filter = {
|
|
32
|
-
"metric.type" = "monitoring.googleapis.com/uptime_check/check_passed"
|
|
33
|
-
"resource.type" = "uptime_url"
|
|
34
|
-
"metric.labels.check_id" = dependency.uptimecheck_id.outputs.uptime_check_ids["<%-systemName%>.<%-serviceName%>"]
|
|
35
|
-
}<% } %>
|
|
23
|
+
telemetry_resource_name = "//container.googleapis.com/projects/${lookup(local.project_vars.locals, "monitoring_project_id", local.project_vars.locals.tribe_project_id)}/locations/europe-west1/clusters/k8s-cluster/k8s/namespaces/<%-serviceName%>"
|
|
36
24
|
}
|
|
37
25
|
)
|
|
@@ -26,11 +26,13 @@ inputs = merge(
|
|
|
26
26
|
local.project_vars.locals,
|
|
27
27
|
local.common_vars.locals,
|
|
28
28
|
{
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
29
|
+
monitoring_project_id = lookup(local.project_vars.locals, "monitoring_project_id", local.project_vars.locals.tribe_project_id),
|
|
30
|
+
notification_channels = dependency.notification_channels.outputs.notification_channels
|
|
31
|
+
uptime_checks = yamldecode(file("${get_terragrunt_dir()}/uptime-checks.yaml")),
|
|
32
|
+
labels = {
|
|
33
|
+
clan = local.common_vars.locals.clan_name
|
|
34
|
+
cc = local.common_vars.locals.cost_center
|
|
35
|
+
jira_project_key = lookup(local.project_vars.locals, "jira_project_key", null)
|
|
34
36
|
}
|
|
35
37
|
}
|
|
36
38
|
)
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
service_name: <%-systemName%>.<%-serviceName%>
|
|
2
|
+
hostname: <%-hostname%>
|
|
3
|
+
path: <%-path%>
|
|
@@ -1,40 +1,36 @@
|
|
|
1
|
-
const
|
|
1
|
+
const validate = {};
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
validate.hostName = (input) => {
|
|
4
4
|
const regex = new RegExp(/^(?:[a-z-]+\.){1,3}[a-z-]+$/g);
|
|
5
|
-
if (input.match(regex))
|
|
6
|
-
return true;
|
|
7
|
-
}
|
|
5
|
+
if (input.match(regex)) return true;
|
|
8
6
|
return 'Hostname must not include path to the page to run the check against or spaces';
|
|
9
7
|
};
|
|
10
8
|
|
|
11
|
-
|
|
12
|
-
if (input.replace(/\s/g, '').length === 3)
|
|
13
|
-
return true;
|
|
14
|
-
}
|
|
9
|
+
validate.systemName = (input) => {
|
|
10
|
+
if (input.replace(/\s/g, '').length === 3) return true;
|
|
15
11
|
return 'System name must be 3 characters';
|
|
16
12
|
};
|
|
17
13
|
|
|
18
|
-
|
|
14
|
+
validate.url = (input) => {
|
|
19
15
|
// eslint-disable-next-line no-useless-escape
|
|
20
16
|
const regex = new RegExp(/^https:\/\/[a-zA-Z]*.[a-zA-Z]*.[a-zA-Z]*\/[a-zA-Z\/+_-]*.$/g);
|
|
21
17
|
if (regex.test(input) || input === '') return true;
|
|
22
18
|
return 'You must enter a valid URL';
|
|
23
19
|
};
|
|
24
20
|
|
|
25
|
-
|
|
21
|
+
validate.instanceID = (input) => {
|
|
26
22
|
if (input.split('/').length === 6) return true;
|
|
27
23
|
return 'You must enter the full instance path (example: projects/example/locations/europe-west1/instances/instanceID)';
|
|
28
24
|
};
|
|
29
25
|
|
|
30
|
-
|
|
26
|
+
validate.databaseId = (input) => {
|
|
31
27
|
if (input.split(':').length === 2) return true;
|
|
32
28
|
return 'You must enter the full database path (example: my-project:databaseID)';
|
|
33
29
|
};
|
|
34
30
|
|
|
35
|
-
|
|
31
|
+
validate.pubSubSubscription = (input) => {
|
|
36
32
|
if (input.split('/').length === 4) return true;
|
|
37
33
|
return 'You must enter the full subscription path (example: projects/example/subscriptions/subscriptionId)';
|
|
38
34
|
};
|
|
39
35
|
|
|
40
|
-
module.exports =
|
|
36
|
+
module.exports = validate;
|
package/package.json
CHANGED
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
const fs = require('fs');
|
|
2
|
-
const yaml = require('js-yaml');
|
|
3
|
-
|
|
4
|
-
const appendIncludeConfigSlo = async (fileContent, originalContentYaml, slosFilePath, inputs) => {
|
|
5
|
-
if (fileContent !== null && fileContent !== '') {
|
|
6
|
-
const configArray = Object.values(originalContentYaml);
|
|
7
|
-
const yamlPullArray = yaml.dump(configArray);
|
|
8
|
-
fs.writeFileSync(slosFilePath, `${yamlPullArray}`);
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
const newPullArray = [];
|
|
12
|
-
|
|
13
|
-
const availabilityConf = {
|
|
14
|
-
display_name: 'Month - Availability',
|
|
15
|
-
slo_id: 'month-availability',
|
|
16
|
-
goal: 0.998,
|
|
17
|
-
calendar_period: 'MONTH',
|
|
18
|
-
type: 'windows_based_sli',
|
|
19
|
-
method: 'boolean_filter',
|
|
20
|
-
window_period: '60s',
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
if (inputs.sli === 'availability') {
|
|
24
|
-
if (inputs.burnRateAlerts === 'no') {
|
|
25
|
-
availabilityConf.alert = {};
|
|
26
|
-
}
|
|
27
|
-
newPullArray.push(availabilityConf);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const errorRateConf = {
|
|
31
|
-
display_name: 'Month - Error rate',
|
|
32
|
-
slo_id: 'month-error-rate',
|
|
33
|
-
goal: 0.999,
|
|
34
|
-
calendar_period: 'MONTH',
|
|
35
|
-
type: 'request_based_sli',
|
|
36
|
-
method: 'good_total_ratio',
|
|
37
|
-
bad_service_filter:
|
|
38
|
-
`metric.type="knative.dev/serving/revision/request_count"
|
|
39
|
-
resource.type="knative_revision"
|
|
40
|
-
metric.labels.response_code_class="5xx"
|
|
41
|
-
resource.labels.service_name="${inputs.serviceName}"`,
|
|
42
|
-
total_service_filter:
|
|
43
|
-
`metric.type="knative.dev/serving/revision/request_count"
|
|
44
|
-
resource.type="knative_revision"
|
|
45
|
-
resource.labels.service_name=${inputs.serviceName}"`,
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
if (inputs.sli === 'error-rate') {
|
|
49
|
-
if (inputs.burnRateAlerts === 'no') {
|
|
50
|
-
errorRateConf.alert = {};
|
|
51
|
-
}
|
|
52
|
-
newPullArray.push(errorRateConf);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
const latencyConf = {
|
|
56
|
-
display_name: 'Month - Latency',
|
|
57
|
-
slo_id: 'month-latency',
|
|
58
|
-
goal: 0.95,
|
|
59
|
-
calendar_period: 'MONTH',
|
|
60
|
-
type: 'request_based_sli',
|
|
61
|
-
method: 'distribution_cut',
|
|
62
|
-
metric_filter:
|
|
63
|
-
`metric.type="knative.dev/serving/revision/request_latencies"
|
|
64
|
-
resource.type="knative_revision"
|
|
65
|
-
resource.labels.service_name="${inputs.serviceName}"`,
|
|
66
|
-
range_min: 0,
|
|
67
|
-
range_max: 100,
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
if (inputs.sli === 'latency') {
|
|
71
|
-
if (inputs.burnRateAlerts === 'no') {
|
|
72
|
-
latencyConf.alert = {};
|
|
73
|
-
}
|
|
74
|
-
newPullArray.push(latencyConf);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
const finalYamlPullArray = yaml.dump(newPullArray);
|
|
78
|
-
fs.appendFileSync(slosFilePath, finalYamlPullArray);
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
const appendIncludeConfigUptime = async (fileContent, uptimeContentYml, uptimeFilePath, inputs) => {
|
|
82
|
-
if (fileContent !== null && fileContent !== '') {
|
|
83
|
-
const configArray = Object.values(uptimeContentYml);
|
|
84
|
-
const yamlPullArray = yaml.dump(configArray);
|
|
85
|
-
fs.writeFileSync(uptimeFilePath, `${yamlPullArray}`);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
const newPullArray = [];
|
|
89
|
-
|
|
90
|
-
newPullArray.push(
|
|
91
|
-
{
|
|
92
|
-
service_name: `${inputs.systemName}.${inputs.serviceName}`,
|
|
93
|
-
hostname: inputs.hostname,
|
|
94
|
-
path: inputs.path,
|
|
95
|
-
},
|
|
96
|
-
);
|
|
97
|
-
|
|
98
|
-
const finalYamlPullArray = yaml.dump(newPullArray);
|
|
99
|
-
fs.appendFileSync(uptimeFilePath, finalYamlPullArray);
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
module.exports = {
|
|
103
|
-
appendIncludeConfigSlo,
|
|
104
|
-
appendIncludeConfigUptime,
|
|
105
|
-
};
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
const ejs = require('ejs');
|
|
2
|
-
|
|
3
|
-
const handleAlerts = (alerts, templates, answers) => {
|
|
4
|
-
const template = templates[`${answers.alertResource}`][`${answers.alert}`];
|
|
5
|
-
const newAlert = ejs.render(JSON.stringify(template), answers);
|
|
6
|
-
|
|
7
|
-
alerts.push(JSON.parse(newAlert));
|
|
8
|
-
return alerts;
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
module.exports = handleAlerts;
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
const fs = require('fs');
|
|
2
|
-
const yaml = require('js-yaml');
|
|
3
|
-
const { appendIncludeConfigSlo } = require('./append');
|
|
4
|
-
|
|
5
|
-
const handleSlosFile = async (answers, slosFilePath) => {
|
|
6
|
-
const {
|
|
7
|
-
serviceName,
|
|
8
|
-
sli,
|
|
9
|
-
systemName,
|
|
10
|
-
burnRateAlerts,
|
|
11
|
-
} = answers;
|
|
12
|
-
|
|
13
|
-
const sloFileContent = fs.readFileSync(slosFilePath, 'utf8');
|
|
14
|
-
|
|
15
|
-
const inputs = {
|
|
16
|
-
...this.answers,
|
|
17
|
-
serviceName,
|
|
18
|
-
sli,
|
|
19
|
-
systemName,
|
|
20
|
-
burnRateAlerts,
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
const originalContentYaml = yaml.load(sloFileContent);
|
|
24
|
-
const fileContent = sloFileContent;
|
|
25
|
-
await appendIncludeConfigSlo(fileContent, originalContentYaml, slosFilePath, inputs);
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
module.exports = handleSlosFile;
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
const fs = require('fs');
|
|
2
|
-
const yaml = require('js-yaml');
|
|
3
|
-
const { appendIncludeConfigUptime } = require('./append');
|
|
4
|
-
|
|
5
|
-
const handleUptimeFile = async (answers, uptimeFilePath) => {
|
|
6
|
-
const {
|
|
7
|
-
serviceName,
|
|
8
|
-
hostname,
|
|
9
|
-
path,
|
|
10
|
-
systemName,
|
|
11
|
-
} = answers;
|
|
12
|
-
|
|
13
|
-
const uptimeFileContent = fs.readFileSync(uptimeFilePath, 'utf8');
|
|
14
|
-
|
|
15
|
-
const inputs = {
|
|
16
|
-
...this.answers,
|
|
17
|
-
serviceName,
|
|
18
|
-
hostname,
|
|
19
|
-
path,
|
|
20
|
-
systemName,
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
const originalContentYaml = yaml.load(uptimeFileContent);
|
|
24
|
-
const fileContent = uptimeFileContent;
|
|
25
|
-
await appendIncludeConfigUptime(fileContent, originalContentYaml, uptimeFilePath, inputs);
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
module.exports = handleUptimeFile;
|