@hiiretail/gcp-infra-cli 0.75.2 → 0.76.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.
|
@@ -4,7 +4,7 @@ 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
|
|
7
|
+
const validator = require('./validate');
|
|
8
8
|
const handleSlosFile = require('./handle-slos');
|
|
9
9
|
const handleUptimeFile = require('./handle-uptime');
|
|
10
10
|
const handleAlerts = require('./handle-alerts');
|
|
@@ -33,14 +33,14 @@ module.exports = class extends BaseGenerator {
|
|
|
33
33
|
choices: (answers) => Object.keys(alertTemplates[`${answers.alertResource}`]),
|
|
34
34
|
},
|
|
35
35
|
{
|
|
36
|
-
when: (response) =>
|
|
36
|
+
when: (response) => ['alerts', 'slos', 'uptime-checks'].includes(response.monitoringResource),
|
|
37
37
|
type: 'input',
|
|
38
38
|
name: 'systemName',
|
|
39
|
-
message: 'Please provide three-letter system name as defined in Styra',
|
|
40
|
-
validate: required &&
|
|
39
|
+
message: 'Please provide three-letter system name as defined in Styra (example: sre, ptf, sda, che, pnp, iam...)',
|
|
40
|
+
validate: required && validator.systemName,
|
|
41
41
|
},
|
|
42
42
|
{
|
|
43
|
-
when: (response) =>
|
|
43
|
+
when: (response) => ['slos', 'uptime-checks'].includes(response.monitoringResource) || response.alertResource === 'cloud_run',
|
|
44
44
|
type: 'input',
|
|
45
45
|
name: 'serviceName',
|
|
46
46
|
message: 'Please provide the namespace where the service resides',
|
|
@@ -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 && validator.url,
|
|
55
55
|
},
|
|
56
56
|
{
|
|
57
57
|
when: (response) => response.alertResource === 'cloud_scheduler',
|
|
@@ -65,34 +65,35 @@ 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 && validator.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 && validator.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 && validator.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 && validator.validHostname,
|
|
90
90
|
},
|
|
91
91
|
{
|
|
92
92
|
when: (response) => response.monitoringResource === 'uptime-checks',
|
|
93
93
|
type: 'input',
|
|
94
94
|
name: 'path',
|
|
95
|
-
message: 'Please provide the path to
|
|
95
|
+
message: 'Please provide the path/endpoint to run the check against',
|
|
96
|
+
default: '/health',
|
|
96
97
|
validate: required,
|
|
97
98
|
},
|
|
98
99
|
{
|
|
@@ -106,7 +107,7 @@ module.exports = class extends BaseGenerator {
|
|
|
106
107
|
when: (response) => response.monitoringResource === 'slos',
|
|
107
108
|
type: 'list',
|
|
108
109
|
name: 'burnRateAlerts',
|
|
109
|
-
message: 'Please select yes if you want to
|
|
110
|
+
message: 'Please select yes if you want to have burn-rate alerts included',
|
|
110
111
|
default: 'yes',
|
|
111
112
|
choices: ['yes', 'no'],
|
|
112
113
|
},
|
|
@@ -114,7 +115,7 @@ module.exports = class extends BaseGenerator {
|
|
|
114
115
|
when: (response) => response.monitoringResource === 'slos' && response.sli === 'availability',
|
|
115
116
|
type: 'confirm',
|
|
116
117
|
name: 'info',
|
|
117
|
-
message: 'WARNING: Make sure
|
|
118
|
+
message: 'WARNING: Make sure an uptime check has been created BEFORE continuing with the creation of this SLO.',
|
|
118
119
|
},
|
|
119
120
|
]);
|
|
120
121
|
}
|
|
@@ -1,37 +1,4 @@
|
|
|
1
1
|
cloud_run:
|
|
2
|
-
error_count:
|
|
3
|
-
display_name: "[P3] <%-systemName%>.<%-serviceName%> | 5xx Error Request Count above 1"
|
|
4
|
-
conditions:
|
|
5
|
-
- display_name: Cloud Run Anthos - 5xx error Request Count above 1
|
|
6
|
-
condition_threshold:
|
|
7
|
-
filter: |
|
|
8
|
-
resource.type="knative_revision"
|
|
9
|
-
resource.labels.service_name="<%-serviceName%>"
|
|
10
|
-
metric.type="knative.dev/serving/revision/request_count"
|
|
11
|
-
metric.labels.response_code_class="5xx"
|
|
12
|
-
threshold_value: 1
|
|
13
|
-
aggregations:
|
|
14
|
-
- alignment_period: 60s
|
|
15
|
-
cross_series_reducer: REDUCE_SUM
|
|
16
|
-
group_by_fields:
|
|
17
|
-
- metric.label.response_code_class
|
|
18
|
-
per_series_aligner: ALIGN_DELTA
|
|
19
|
-
documentation:
|
|
20
|
-
content: <% if (runbookLink) { %>[Runbook](<%-runbookLink%>)<%} else { %> <% } %>
|
|
21
|
-
error_rate:
|
|
22
|
-
display_name: "[P3] <%-systemName%>.<%-serviceName%> | High 5xx Error Rate"
|
|
23
|
-
conditions:
|
|
24
|
-
- display_name: Cloud Run Anthos - 3% of all requests during 10min are 5xx
|
|
25
|
-
condition_monitoring_query_language:
|
|
26
|
-
query: |
|
|
27
|
-
fetch knative_revision::knative.dev/serving/revision/request_count
|
|
28
|
-
| filter service_name = "store-data-resolver"
|
|
29
|
-
| align int_mean_aligner(10m)
|
|
30
|
-
| group_by [], sum(if(metric.response_code_class == '5xx', val(), 0)) / sum(val())
|
|
31
|
-
| condition val() > 0.03
|
|
32
|
-
| every 10m
|
|
33
|
-
documentation:
|
|
34
|
-
content: <% if (runbookLink) { %>[Runbook](<%-runbookLink%>)<%} else { %> <% } %>
|
|
35
2
|
request_latency:
|
|
36
3
|
display_name: "[P3] <%-systemName%>.<%-serviceName%> | High Request Latency"
|
|
37
4
|
conditions:
|
|
@@ -45,7 +12,6 @@ cloud_run:
|
|
|
45
12
|
duration: 300s
|
|
46
13
|
aggregations:
|
|
47
14
|
- alignment_period: 60s
|
|
48
|
-
cross_series_reducer: REDUCE_NONE
|
|
49
15
|
per_series_aligner: ALIGN_PERCENTILE_95
|
|
50
16
|
documentation:
|
|
51
17
|
content: <% if (runbookLink) { %>[Runbook](<%-runbookLink%>)<%} else { %> <% } %>
|
|
@@ -63,13 +29,12 @@ cloud_scheduler:
|
|
|
63
29
|
threshold_value: 1
|
|
64
30
|
aggregations:
|
|
65
31
|
- alignment_period: 60s
|
|
66
|
-
cross_series_reducer: REDUCE_NONE
|
|
67
32
|
per_series_aligner: ALIGN_COUNT
|
|
68
33
|
documentation:
|
|
69
34
|
content: <% if (runbookLink) { %>[Runbook](<%-runbookLink%>)<%} else { %> <% } %>
|
|
70
35
|
cloud_sql:
|
|
71
36
|
cpu_over_65:
|
|
72
|
-
display_name: "[P3] <%-systemName%> - CloudSQL | <%-databaseId%> - CPU over 65%"
|
|
37
|
+
display_name: "[P3] <%-systemName%> - CloudSQL | <%-databaseId.substring(databaseId.lastIndexOf(':') + 1)%> - CPU over 65%"
|
|
73
38
|
conditions:
|
|
74
39
|
- display_name: Cloud SQL Database - CPU utilization above 65% over 5 min
|
|
75
40
|
condition_threshold:
|
|
@@ -81,12 +46,11 @@ cloud_sql:
|
|
|
81
46
|
duration: 300s
|
|
82
47
|
aggregations:
|
|
83
48
|
- alignment_period: 60s
|
|
84
|
-
cross_series_reducer: REDUCE_NONE
|
|
85
49
|
per_series_aligner: ALIGN_MAX
|
|
86
50
|
documentation:
|
|
87
51
|
content: <% if (runbookLink) { %>[Runbook](<%-runbookLink%>)<%} else { %> <% } %>
|
|
88
52
|
cpu_over_85:
|
|
89
|
-
display_name: "[P3] <%-systemName%> - CloudSQL | <%-databaseId%> - CPU over 85%"
|
|
53
|
+
display_name: "[P3] <%-systemName%> - CloudSQL | <%-databaseId.substring(databaseId.lastIndexOf(':') + 1)%> - CPU over 85%"
|
|
90
54
|
conditions:
|
|
91
55
|
- display_name: "Cloud SQL Database - CPU-usage above 85% over 1 min"
|
|
92
56
|
condition_threshold:
|
|
@@ -98,12 +62,11 @@ cloud_sql:
|
|
|
98
62
|
duration: 60s
|
|
99
63
|
aggregations:
|
|
100
64
|
- alignment_period: 60s
|
|
101
|
-
cross_series_reducer: REDUCE_NONE
|
|
102
65
|
per_series_aligner: ALIGN_MAX
|
|
103
66
|
documentation:
|
|
104
67
|
content: <% if (runbookLink) { %>[Runbook](<%-runbookLink%>)<%} else { %> <% } %>
|
|
105
68
|
cpu_over_90:
|
|
106
|
-
display_name: "[P3] <%-systemName%> - CloudSQL | <%-databaseId%> - CPU over 90%"
|
|
69
|
+
display_name: "[P3] <%-systemName%> - CloudSQL | <%-databaseId.substring(databaseId.lastIndexOf(':') + 1)%> - CPU over 90%"
|
|
107
70
|
conditions:
|
|
108
71
|
- display_name: Cloud SQL Database - CPU-usage above 90%
|
|
109
72
|
condition_threshold:
|
|
@@ -114,63 +77,11 @@ cloud_sql:
|
|
|
114
77
|
threshold_value: 0.9
|
|
115
78
|
aggregations:
|
|
116
79
|
- alignment_period: 60s
|
|
117
|
-
cross_series_reducer: REDUCE_NONE
|
|
118
80
|
per_series_aligner: ALIGN_MAX
|
|
119
81
|
documentation:
|
|
120
82
|
content: <% if (runbookLink) { %>[Runbook](<%-runbookLink%>)<%} else { %> <% } %>
|
|
121
|
-
memory_over_50:
|
|
122
|
-
display_name: "[P3] <%-systemName%> - CloudSQL | <%-databaseId%> - Memory over 50%"
|
|
123
|
-
conditions:
|
|
124
|
-
- display_name: Cloud SQL Database - Memory utilization above 50% over 5 min
|
|
125
|
-
condition_threshold:
|
|
126
|
-
filter: |
|
|
127
|
-
resource.type="cloudsql_database"
|
|
128
|
-
resource.labels.database_id="<%-databaseId%>"
|
|
129
|
-
metric.type="cloudsql.googleapis.com/database/memory/utilization"
|
|
130
|
-
threshold_value: 50
|
|
131
|
-
duration: 300s
|
|
132
|
-
aggregations:
|
|
133
|
-
- alignment_period: 60s
|
|
134
|
-
cross_series_reducer: REDUCE_NONE
|
|
135
|
-
per_series_aligner: ALIGN_MAX
|
|
136
|
-
documentation:
|
|
137
|
-
content: <% if (runbookLink) { %>[Runbook](<%-runbookLink%>)<%} else { %> <% } %>
|
|
138
|
-
memory_over_75:
|
|
139
|
-
display_name: "[P3] <%-systemName%> - CloudSQL | <%-databaseId%> - Memory over 75%"
|
|
140
|
-
conditions:
|
|
141
|
-
- display_name: Cloud SQL Database - Memory utilization above 75% over 5 min
|
|
142
|
-
condition_threshold:
|
|
143
|
-
filter: |
|
|
144
|
-
resource.type="cloudsql_database"
|
|
145
|
-
resource.labels.database_id="<%-databaseId%>"
|
|
146
|
-
metric.type="cloudsql.googleapis.com/database/memory/utilization"
|
|
147
|
-
threshold_value: 75
|
|
148
|
-
duration: 300s
|
|
149
|
-
aggregations:
|
|
150
|
-
- alignment_period: 60s
|
|
151
|
-
cross_series_reducer: REDUCE_NONE
|
|
152
|
-
per_series_aligner: ALIGN_MAX
|
|
153
|
-
documentation:
|
|
154
|
-
content: <% if (runbookLink) { %>[Runbook](<%-runbookLink%>)<%} else { %> <% } %>
|
|
155
|
-
memory_over_90:
|
|
156
|
-
display_name: "[P3] <%-systemName%> - CloudSQL | <%-databaseId%> - Memory over 90%"
|
|
157
|
-
conditions:
|
|
158
|
-
- display_name: Cloud SQL Database - Memory utilization above 90%
|
|
159
|
-
condition_threshold:
|
|
160
|
-
filter: |
|
|
161
|
-
resource.type="cloudsql_database"
|
|
162
|
-
resource.labels.database_id="<%-databaseId%>"
|
|
163
|
-
metric.type="cloudsql.googleapis.com/database/memory/utilization"
|
|
164
|
-
threshold_value: 90
|
|
165
|
-
duration: 60s
|
|
166
|
-
aggregations:
|
|
167
|
-
- alignment_period: 60s
|
|
168
|
-
cross_series_reducer: REDUCE_NONE
|
|
169
|
-
per_series_aligner: ALIGN_MAX
|
|
170
|
-
documentation:
|
|
171
|
-
content: <% if (runbookLink) { %>[Runbook](<%-runbookLink%>)<%} else { %> <% } %>
|
|
172
83
|
query_over_1s:
|
|
173
|
-
display_name: "[P4] <%-systemName%> - CloudSQL | <%-databaseId%> - Query resolve time"
|
|
84
|
+
display_name: "[P4] <%-systemName%> - CloudSQL | <%-databaseId.substring(databaseId.lastIndexOf(':') + 1)%> - Query resolve time"
|
|
174
85
|
conditions:
|
|
175
86
|
- display_name: Cloud SQL Instance Database - Per query execution times above 1000 ms
|
|
176
87
|
condition_threshold:
|
|
@@ -181,13 +92,12 @@ cloud_sql:
|
|
|
181
92
|
threshold_value: 1000000
|
|
182
93
|
aggregations:
|
|
183
94
|
- alignment_period: 60s
|
|
184
|
-
cross_series_reducer: REDUCE_NONE
|
|
185
95
|
per_series_aligner: ALIGN_DELTA
|
|
186
96
|
documentation:
|
|
187
97
|
content: <% if (runbookLink) { %>[Runbook](<%-runbookLink%>)<%} else { %> <% } %>
|
|
188
98
|
memorystore:
|
|
189
99
|
memory_over_50:
|
|
190
|
-
display_name: "[P4] <%-systemName%> - Memorystore | <%-instanceId%> - Memory over 50%"
|
|
100
|
+
display_name: "[P4] <%-systemName%> - Memorystore | <%-instanceId.substring(instanceId.lastIndexOf('/') + 1)%> - Memory over 50%"
|
|
191
101
|
conditions:
|
|
192
102
|
- display_name: Memorystore Redis Instance - Memory Usage above 50% over 5 min
|
|
193
103
|
condition_threshold:
|
|
@@ -199,12 +109,11 @@ memorystore:
|
|
|
199
109
|
duration: 300s
|
|
200
110
|
aggregations:
|
|
201
111
|
- alignment_period: 60s
|
|
202
|
-
cross_series_reducer: REDUCE_NONE
|
|
203
112
|
per_series_aligner: ALIGN_MAX
|
|
204
113
|
documentation:
|
|
205
114
|
content: <% if (runbookLink) { %>[Runbook](<%-runbookLink%>)<%} else { %> <% } %>
|
|
206
115
|
memory_over_75:
|
|
207
|
-
display_name: "[P4] <%-systemName%> - Memorystore | <%-instanceId%> - Memory over 75%"
|
|
116
|
+
display_name: "[P4] <%-systemName%> - Memorystore | <%-instanceId.substring(instanceId.lastIndexOf('/') + 1)%> - Memory over 75%"
|
|
208
117
|
conditions:
|
|
209
118
|
- display_name: Memorystore Redis Instance - Memory Usage above 75% for 5min
|
|
210
119
|
condition_threshold:
|
|
@@ -216,12 +125,11 @@ memorystore:
|
|
|
216
125
|
duration: 300s
|
|
217
126
|
aggregations:
|
|
218
127
|
- alignment_period: 60s
|
|
219
|
-
cross_series_reducer: REDUCE_NONE
|
|
220
128
|
per_series_aligner: ALIGN_MAX
|
|
221
129
|
documentation:
|
|
222
130
|
content: <% if (runbookLink) { %>[Runbook](<%-runbookLink%>)<%} else { %> <% } %>
|
|
223
131
|
memory_over_90:
|
|
224
|
-
display_name: "[P2] <%-systemName%> - Memorystore | <%-instanceId%> - Memory over 90%"
|
|
132
|
+
display_name: "[P2] <%-systemName%> - Memorystore | <%-instanceId.substring(instanceId.lastIndexOf('/') + 1)%> - Memory over 90%"
|
|
225
133
|
conditions:
|
|
226
134
|
- display_name: Memorystore Redis Instance - Memory Usage above 90%
|
|
227
135
|
condition_threshold:
|
|
@@ -233,13 +141,12 @@ memorystore:
|
|
|
233
141
|
duration: 60s
|
|
234
142
|
aggregations:
|
|
235
143
|
- alignment_period: 60s
|
|
236
|
-
cross_series_reducer: REDUCE_NONE
|
|
237
144
|
per_series_aligner: ALIGN_MAX
|
|
238
145
|
documentation:
|
|
239
146
|
content: <% if (runbookLink) { %>[Runbook](<%-runbookLink%>)<%} else { %> <% } %>
|
|
240
147
|
pub_sub:
|
|
241
148
|
unacknowledged_messages:
|
|
242
|
-
display_name: "[P4] <%-systemName%> - Pub/Sub | <%-subscriptionId%> - Undelivered message(s)"
|
|
149
|
+
display_name: "[P4] <%-systemName%> - Pub/Sub | <%-subscriptionId.substring(subscriptionId.lastIndexOf('/') + 1)%> - Undelivered message(s)"
|
|
243
150
|
conditions:
|
|
244
151
|
- display_name: Cloud Pub/Sub Subscription - Undelivered messages above 1 for 5 min
|
|
245
152
|
condition_threshold:
|
|
@@ -251,7 +158,6 @@ pub_sub:
|
|
|
251
158
|
duration: 300s
|
|
252
159
|
aggregations:
|
|
253
160
|
- alignment_period: 60s
|
|
254
|
-
cross_series_reducer: REDUCE_NONE
|
|
255
161
|
per_series_aligner: ALIGN_MEAN
|
|
256
162
|
documentation:
|
|
257
163
|
content: <% if (runbookLink) { %>[Runbook](<%-runbookLink%>)<%} else { %> <% } %>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
const
|
|
1
|
+
const validator = {};
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
validator.hostName = (input) => {
|
|
4
4
|
const regex = new RegExp(/^(?:[a-z-]+\.){1,3}[a-z-]+$/g);
|
|
5
5
|
if (input.match(regex)) {
|
|
6
6
|
return true;
|
|
@@ -8,18 +8,33 @@ helper.validHostname = (input) => {
|
|
|
8
8
|
return 'Hostname must not include path to the page to run the check against or spaces';
|
|
9
9
|
};
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
validator.systemName = (input) => {
|
|
12
12
|
if (input.replace(/\s/g, '').length === 3) {
|
|
13
13
|
return true;
|
|
14
14
|
}
|
|
15
15
|
return 'System name must be 3 characters';
|
|
16
16
|
};
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
validator.url = (input) => {
|
|
19
19
|
// eslint-disable-next-line no-useless-escape
|
|
20
20
|
const regex = new RegExp(/^https:\/\/[a-zA-Z]*.[a-zA-Z]*.[a-zA-Z]*\/[a-zA-Z\/+_-]*.$/g);
|
|
21
21
|
if (regex.test(input) || input === '') return true;
|
|
22
|
-
return '
|
|
22
|
+
return 'You must enter a valid URL';
|
|
23
23
|
};
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
validator.instanceID = (input) => {
|
|
26
|
+
if (input.split('/').length === 6) return true;
|
|
27
|
+
return 'You must enter the full instance path (example: projects/example/locations/europe-west1/instances/instanceID)';
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
validator.databaseId = (input) => {
|
|
31
|
+
if (input.split(':').length === 2) return true;
|
|
32
|
+
return 'You must enter the full database path (example: my-project:databaseID)';
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
validator.pubSubSubscription = (input) => {
|
|
36
|
+
if (input.split('/').length === 4) return true;
|
|
37
|
+
return 'You must enter the full subscription path (example: projects/example/subscriptions/subscriptionId)';
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
module.exports = validator;
|