diff --git a/.cloud-repo-tools.json b/.cloud-repo-tools.json index 7f79b3da..72bd859e 100644 --- a/.cloud-repo-tools.json +++ b/.cloud-repo-tools.json @@ -5,6 +5,13 @@ "client_reference_url": "https://cloud.google.com/nodejs/docs/reference/monitoring/latest/", "release_quality": "beta", "samples": [ + { + "id": "alerts", + "name": "Alert Policies", + "file": "alerts.js", + "docs_link": "https://cloud.google.com/monitoring/docs", + "usage": "node alerts.js --help" + }, { "id": "metrics", "name": "Metrics", diff --git a/.gitignore b/.gitignore index b7d40760..082cf01e 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,10 @@ .nyc_output docs/ out/ +build/ system-test/secrets.js system-test/*key.json *.lock +.DS_Store +google-cloud-logging-winston-*.tgz +google-cloud-logging-bunyan-*.tgz \ No newline at end of file diff --git a/README.md b/README.md index 2f451193..84f1b395 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +[//]: # "This README.md file is auto-generated, all changes to this file will be lost." +[//]: # "To regenerate it, use `npm run generate-scaffolding`." Google Cloud Platform logo # [Stackdriver Monitoring: Node.js Client](https://github.com/googleapis/nodejs-monitoring) @@ -126,6 +128,7 @@ has instructions for running the samples. | Sample | Source Code | Try it | | --------------------------- | --------------------------------- | ------ | +| Alert Policies | [source code](https://github.com/googleapis/nodejs-monitoring/blob/master/samples/alerts.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-monitoring&page=editor&open_in_editor=samples/alerts.js,samples/README.md) | | Metrics | [source code](https://github.com/googleapis/nodejs-monitoring/blob/master/samples/metrics.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-monitoring&page=editor&open_in_editor=samples/metrics.js,samples/README.md) | | Uptime Config | [source code](https://github.com/googleapis/nodejs-monitoring/blob/master/samples/uptime.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-monitoring&page=editor&open_in_editor=samples/uptime.js,samples/README.md) | @@ -157,4 +160,4 @@ See [LICENSE](https://github.com/googleapis/nodejs-monitoring/blob/master/LICENS [client-docs]: https://cloud.google.com/nodejs/docs/reference/monitoring/latest/ [product-docs]: https://cloud.google.com/monitoring/docs -[shell_img]: //gstatic.com/cloudssh/images/open-btn.png +[shell_img]: https://gstatic.com/cloudssh/images/open-btn.png diff --git a/package.json b/package.json index f676c61f..cb388bca 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,7 @@ "lodash.union": "^4.6.0" }, "devDependencies": { - "@google-cloud/nodejs-repo-tools": "^2.2.3", + "@google-cloud/nodejs-repo-tools": "^2.3.0", "async": "^2.5.0", "codecov": "^3.0.0", "eslint": "^4.9.0", diff --git a/samples/.gitignore b/samples/.gitignore new file mode 100644 index 00000000..e3fd3ac1 --- /dev/null +++ b/samples/.gitignore @@ -0,0 +1 @@ +policies_backup.json \ No newline at end of file diff --git a/samples/README.md b/samples/README.md index 37d70aa3..c9599478 100644 --- a/samples/README.md +++ b/samples/README.md @@ -1,3 +1,5 @@ +[//]: # "This README.md file is auto-generated, all changes to this file will be lost." +[//]: # "To regenerate it, use `npm run generate-scaffolding`." Google Cloud Platform logo # Stackdriver Monitoring: Node.js Samples @@ -10,6 +12,7 @@ * [Before you begin](#before-you-begin) * [Samples](#samples) + * [Alert Policies](#alert-policies) * [Metrics](#metrics) * [Uptime Config](#uptime-config) @@ -21,9 +24,56 @@ library's README. ## Samples +### Alert Policies + +View the [source code][alerts_0_code]. + +[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-monitoring&page=editor&open_in_editor=samples/alerts.js,samples/README.md) + +__Usage:__ `node alerts.js --help` + +``` +alerts.js + +Commands: + alerts.js backup Save alert policies to a ./policies_backup.json file. + alerts.js restore Restore alert policies from a ./policies_backup.json file. + alerts.js replace Replace the notification channels of the specified alert policy. + alerts.js disable [filter] Disables policies that match the given filter. + alerts.js enable [filter] Enables policies that match the given filter. + +Options: + --version Show version number [boolean] + --alertPolicyName [string] + --help Show help [boolean] + +Examples: + node alerts.js backup my-project-id Backup policies. + node alerts.js restore my-project-id Restore policies. + node alerts.js replace Replace the notification channels of the specified alert + projects/my-project-id/alertPolicies/12345 channel-1 policy. + channel-2 channel-3 + node alerts.js disable my-project-id "(NOT Disables policies that match the given filter. + display_name.empty OR NOT description.empty) AND + user_labels='active'" + node alerts.js disable my-project-id "description:'cloud'" Disables policies that match the given filter. + node alerts.js disable my-project-id Disables policies that match the given filter. + "display_name=monitoring.regex.full_match('Temp \d{4}')" + node alerts.js enable my-project-id "(NOT display_name.empty Enables policies that match the given filter. + OR NOT description.empty) AND user_labels='active'" + node alerts.js enable my-project-id "description:'cloud'" Enables policies that match the given filter. + node alerts.js enable my-project-id Enables policies that match the given filter. + "display_name=monitoring.regex.full_match('Temp \d{4}')" + +For more information, see https://cloud.google.com/monitoring/docs/ +``` + +[alerts_0_docs]: https://cloud.google.com/monitoring/docs +[alerts_0_code]: alerts.js + ### Metrics -View the [source code][metrics_0_code]. +View the [source code][metrics_1_code]. [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-monitoring&page=editor&open_in_editor=samples/metrics.js,samples/README.md) @@ -52,7 +102,7 @@ Commands: Options: --version Show version number [boolean] - --projectId, -p [string] + --projectId, -p [string] [default: "nodejs-docs-samples"] --help Show help [boolean] Examples: @@ -71,12 +121,12 @@ Examples: For more information, see https://cloud.google.com/monitoring/docs ``` -[metrics_0_docs]: https://cloud.google.com/monitoring/docs -[metrics_0_code]: metrics.js +[metrics_1_docs]: https://cloud.google.com/monitoring/docs +[metrics_1_code]: metrics.js ### Uptime Config -View the [source code][uptime_1_code]. +View the [source code][uptime_2_code]. [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-monitoring&page=editor&open_in_editor=samples/uptime.js,samples/README.md) @@ -86,7 +136,7 @@ __Usage:__ `node uptime.js --help` uptime.js Commands: - uptime.js create [projectId] Creates an uptime check config. + uptime.js create [projectId] Creates an uptime check config. uptime.js list [projectId] Lists uptime check configs. uptime.js list-ips Lists uptime check config IPs. uptime.js get [projectId] Gets an uptime check config. @@ -94,11 +144,11 @@ Commands: Options: --version Show version number [boolean] - --projectId, -p [string] + --projectId, -p [string] [default: "nodejs-docs-samples"] --help Show help [boolean] Examples: - node uptime.js create my-instance Create an uptime check for a "my-instance" GCE instance. + node uptime.js create mydomain.com Create an uptime check. node uptime.js list List all uptime check configs. node uptime.js list "resource.type = gce_instance AND List all uptime check configs for a specific GCE resource.label.instance_id = mongodb" instance. @@ -109,8 +159,8 @@ Examples: For more information, see https://cloud.google.com/monitoring/uptime-checks/ ``` -[uptime_1_docs]: https://cloud.google.com/monitoring/docs -[uptime_1_code]: uptime.js +[uptime_2_docs]: https://cloud.google.com/monitoring/docs +[uptime_2_code]: uptime.js -[shell_img]: //gstatic.com/cloudssh/images/open-btn.png +[shell_img]: https://gstatic.com/cloudssh/images/open-btn.png [shell_link]: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-monitoring&page=editor&open_in_editor=samples/README.md diff --git a/samples/alerts.js b/samples/alerts.js new file mode 100644 index 00000000..90dd4b64 --- /dev/null +++ b/samples/alerts.js @@ -0,0 +1,361 @@ +/** + * Copyright 2018, Google, Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * This application demonstrates how to perform basic operations on alerting + * policies with the Google Stackdriver Monitoring API. + * + * For more information, see https://cloud.google.com/monitoring/docs/. + */ + +'use strict'; + +function backupPolicies(projectId) { + // [START monitoring_alert_backup_policies] + const fs = require('fs'); + + // Imports the Google Cloud client library + const monitoring = require('@google-cloud/monitoring'); + + // Creates a client + const client = new monitoring.AlertPolicyServiceClient(); + + /** + * TODO(developer): Uncomment the following lines before running the sample. + */ + // const projectId = 'YOUR_PROJECT_ID'; + + const listAlertPoliciesRequest = { + name: client.projectPath(projectId), + }; + + client + .listAlertPolicies(listAlertPoliciesRequest) + .then(results => { + const policies = results[0]; + + fs.writeFileSync( + './policies_backup.json', + JSON.stringify(policies, null, 2), + 'utf-8' + ); + + console.log('Saved policies to ./policies_backup.json'); + }) + .catch(err => { + console.error('ERROR:', err); + }); + // [START monitoring_alert_backup_policies] +} + +function restorePolicies(projectId) { + // Note: The policies are restored one at a time because I get 'service + // unavailable' when I try to create multiple alerts simultaneously. + // [START monitoring_alert_restore_policies] + const fs = require('fs'); + + // Imports the Google Cloud client library + const monitoring = require('@google-cloud/monitoring'); + + // Creates a client + const client = new monitoring.AlertPolicyServiceClient(); + + /** + * TODO(developer): Uncomment the following lines before running the sample. + */ + // const projectId = 'YOUR_PROJECT_ID'; + + console.log('Loading policies from ./policies_backup.json'); + const fileContent = fs.readFileSync('./policies_backup.json', 'utf-8'); + const policies = JSON.parse(fileContent); + + let promise = Promise.resolve(); + + policies.forEach(policy => { + // Restore each policy one at a time + promise = promise + .then(() => doesAlertPolicyExist(policy.name)) + .then(exists => { + if (exists) { + return client.updateAlertPolicy({alertPolicy: policy}); + } + + // Clear away output-only fields + delete policy.name; + delete policy.creationRecord; + delete policy.mutationRecord; + policy.conditions.forEach(condition => delete condition.name); + + return client.createAlertPolicy({ + name: client.projectPath(projectId), + alertPolicy: policy, + }); + }) + .then(response => { + const policy = response[0]; + console.log(`Restored ${policy.name}.`); + }); + }); + + promise.catch(err => { + console.error('ERROR:', err); + }); + + function doesAlertPolicyExist(name) { + return client + .getAlertPolicy({name: name}) + .then(() => true) + .catch(err => { + if (err && err.code === 5) { + // Error code 5 comes from the google.rpc.code.NOT_FOUND protobuf + return false; + } + return Promise.reject(err); + }); + } + // [START monitoring_alert_restore_policies] +} + +function replaceChannels(projectId, alertPolicyId, channelIds) { + // [START monitoring_alert_replace_channels] + // Imports the Google Cloud client library + const monitoring = require('@google-cloud/monitoring'); + + // Creates clients + const alertClient = new monitoring.AlertPolicyServiceClient(); + const notificationClient = new monitoring.NotificationChannelServiceClient(); + + /** + * TODO(developer): Uncomment the following lines before running the sample. + */ + // const projectId = 'YOUR_PROJECT_ID'; + // const alertPolicyId = '123456789012314'; + // const channelIds = [ + // 'channel-1', + // 'channel-2', + // 'channel-3', + // ]; + + const notificationChannels = channelIds.map(id => + notificationClient.notificationChannelPath(projectId, id) + ); + + const updateAlertPolicyRequest = { + updateMask: {paths: ['notification_channels']}, + alertPolicy: { + name: alertClient.alertPolicyPath(projectId, alertPolicyId), + notificationChannels: notificationChannels, + }, + }; + + alertClient + .updateAlertPolicy(updateAlertPolicyRequest) + .then(results => { + const alertPolicy = results[0]; + console.log(`Updated ${alertPolicy.name}.`); + }) + .catch(err => { + console.error('ERROR:', err); + }); + // [END monitoring_alert_replace_channels] +} + +function disablePolicies(projectId, filter) { + // [START monitoring_alert_disable_policies] + // Imports the Google Cloud client library + const monitoring = require('@google-cloud/monitoring'); + + // Creates a client + const client = new monitoring.AlertPolicyServiceClient(); + + /** + * TODO(developer): Uncomment the following lines before running the sample. + */ + // const projectId = 'YOUR_PROJECT_ID'; + // const filter = 'A filter for selecting policies, e.g. user_labels="active"'; + + const listAlertPoliciesRequest = { + name: client.projectPath(projectId), + // See https://cloud.google.com/monitoring/alerting/docs/sorting-and-filtering + filter: filter, + }; + + client + .listAlertPolicies(listAlertPoliciesRequest) + .then(results => { + const policies = results[0]; + + const tasks = policies + .map(policy => { + return { + updateMask: {paths: ['disabled']}, + alertPolicy: { + name: policy.name, + disabled: true, + }, + }; + }) + .map(updateAlertPolicyRequest => { + return client.updateAlertPolicy(updateAlertPolicyRequest); + }); + + // Wait for all policies to be disabled + return Promise.all(tasks); + }) + .then(responses => { + responses.forEach(response => { + const alertPolicy = response[0]; + console.log(`Disabled ${alertPolicy.name}.`); + }); + }) + .catch(err => { + console.error('ERROR:', err); + }); + // [END monitoring_alert_disable_policies] +} + +function enablePolicies(projectId, filter) { + // [START monitoring_alert_enable_policies] + // Imports the Google Cloud client library + const monitoring = require('@google-cloud/monitoring'); + + // Creates a client + const client = new monitoring.AlertPolicyServiceClient(); + + /** + * TODO(developer): Uncomment the following lines before running the sample. + */ + // const projectId = 'YOUR_PROJECT_ID'; + // const filter = 'A filter for selecting policies, e.g. description:"cloud"'; + + const listAlertPoliciesRequest = { + name: client.projectPath(projectId), + // See https://cloud.google.com/monitoring/alerting/docs/sorting-and-filtering + filter: filter, + }; + + client + .listAlertPolicies(listAlertPoliciesRequest) + .then(results => { + const policies = results[0]; + + const tasks = policies + .map(policy => { + return { + updateMask: {paths: ['disabled']}, + alertPolicy: { + name: policy.name, + disabled: false, + }, + }; + }) + .map(updateAlertPolicyRequest => + client.updateAlertPolicy(updateAlertPolicyRequest) + ); + + // Wait for all policies to be enabled + return Promise.all(tasks); + }) + .then(responses => { + responses.forEach(response => { + const alertPolicy = response[0]; + console.log(`Enabled ${alertPolicy.name}.`); + }); + }) + .catch(err => { + console.error('ERROR:', err); + }); + // [END monitoring_alert_enable_policies] +} + +require(`yargs`) + .demand(1) + .command( + `backup `, + `Save alert policies to a ./policies_backup.json file.`, + {}, + opts => backupPolicies(opts.projectId, opts.filter || '') + ) + .command( + `restore `, + `Restore alert policies from a ./policies_backup.json file.`, + {}, + opts => restorePolicies(opts.projectId, opts.filter || '') + ) + .command( + `replace `, + `Replace the notification channels of the specified alert policy.`, + {}, + opts => { + const parts = opts.alertPolicyName.split('/'); + const channelIds = opts.channelNames.map(name => name.split('/')[3]); + replaceChannels(parts[1], parts[3], channelIds); + } + ) + .command( + `disable [filter]`, + `Disables policies that match the given filter.`, + {}, + opts => disablePolicies(opts.projectId, opts.filter || ``) + ) + .command( + `enable [filter]`, + `Enables policies that match the given filter.`, + {}, + opts => enablePolicies(opts.projectId, opts.filter || ``) + ) + .options({ + alertPolicyName: { + type: 'string', + requiresArg: true, + }, + }) + .example(`node $0 backup my-project-id`, `Backup policies.`) + .example(`node $0 restore my-project-id`, `Restore policies.`) + .example( + `node $0 replace projects/my-project-id/alertPolicies/12345 channel-1 channel-2 channel-3`, + `Replace the notification channels of the specified alert policy.` + ) + .example( + `node $0 disable my-project-id "(NOT display_name.empty OR NOT description.empty) AND user_labels='active'"`, + `Disables policies that match the given filter.` + ) + .example( + `node $0 disable my-project-id "description:'cloud'"`, + `Disables policies that match the given filter.` + ) + .example( + `node $0 disable my-project-id "display_name=monitoring.regex.full_match('Temp \\d{4}')"`, + `Disables policies that match the given filter.` + ) + .example( + `node $0 enable my-project-id "(NOT display_name.empty OR NOT description.empty) AND user_labels='active'"`, + `Enables policies that match the given filter.` + ) + .example( + `node $0 enable my-project-id "description:'cloud'"`, + `Enables policies that match the given filter.` + ) + .example( + `node $0 enable my-project-id "display_name=monitoring.regex.full_match('Temp \\d{4}')"`, + `Enables policies that match the given filter.` + ) + .wrap(120) + .recommendCommands() + .epilogue( + `For more information, see https://cloud.google.com/monitoring/docs/` + ) + .help() + .strict().argv; diff --git a/samples/package-lock.json b/samples/package-lock.json index f14797e6..74021cdc 100644 --- a/samples/package-lock.json +++ b/samples/package-lock.json @@ -10769,9 +10769,9 @@ } }, "@google-cloud/nodejs-repo-tools": { - "version": "2.2.6", - "resolved": "https://registry.npmjs.org/@google-cloud/nodejs-repo-tools/-/nodejs-repo-tools-2.2.6.tgz", - "integrity": "sha512-bDEgNBAJ8kfYWrpifg+D7rXs8NUBUUeu2I6NWkcL9IOXg86rblu7xnhFHRxBMcvytJ+7WY4pvkCLxO1v3QBsXg==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@google-cloud/nodejs-repo-tools/-/nodejs-repo-tools-2.3.0.tgz", + "integrity": "sha512-c8dIGESnNkmM88duFxGHvMQP5QKPgp/sfJq0QhC6+gOcJC7/PKjqd0PkmgPPeIgVl6SXy5Zf/KLbxnJUVgNT1Q==", "dev": true, "requires": { "ava": "0.25.0", @@ -10782,6 +10782,7 @@ "lodash": "4.17.5", "nyc": "11.4.1", "proxyquire": "1.8.0", + "semver": "5.5.0", "sinon": "4.3.0", "string": "3.3.3", "supertest": "3.0.0", @@ -16133,9 +16134,9 @@ "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" }, "qs": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", - "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==", + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", "dev": true }, "query-string": { @@ -16709,7 +16710,7 @@ "formidable": "1.2.1", "methods": "1.1.2", "mime": "1.6.0", - "qs": "6.5.1", + "qs": "6.5.2", "readable-stream": "2.3.6" } }, diff --git a/samples/package.json b/samples/package.json index c764674c..1ae76296 100644 --- a/samples/package.json +++ b/samples/package.json @@ -16,7 +16,7 @@ "yargs": "11.1.0" }, "devDependencies": { - "@google-cloud/nodejs-repo-tools": "2.2.6", + "@google-cloud/nodejs-repo-tools": "2.3.0", "ava": "0.25.0", "proxyquire": "2.0.1", "sinon": "4.5.0" diff --git a/samples/system-test/alerts.test.js b/samples/system-test/alerts.test.js new file mode 100644 index 00000000..5a04d34f --- /dev/null +++ b/samples/system-test/alerts.test.js @@ -0,0 +1,190 @@ +/** + * Copyright 2017, Google, Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +'use strict'; + +const fs = require(`fs`); +const monitoring = require(`@google-cloud/monitoring`); +const path = require(`path`); +const test = require(`ava`); +const tools = require(`@google-cloud/nodejs-repo-tools`); + +const client = new monitoring.AlertPolicyServiceClient(); +const channelClient = new monitoring.NotificationChannelServiceClient(); +const cwd = path.join(__dirname, `..`); +const projectId = process.env.GCLOUD_PROJECT; + +let policyOneName, policyTwoName, channelName; + +test.before(tools.checkCredentials); + +test.before(async () => { + let results = await client.createAlertPolicy({ + name: client.projectPath(projectId), + alertPolicy: { + displayName: 'first_policy', + combiner: 1, + conditions: [ + { + displayName: 'Condition 1', + conditionAbsent: { + filter: `metric.type = "cloudfunctions.googleapis.com/function/execution_count"`, + aggregations: [ + { + alignmentPeriod: { + seconds: 60, + }, + perSeriesAligner: 1, + crossSeriesReducer: 0, + }, + ], + duration: { + seconds: 60, + }, + trigger: { + count: 1, + }, + }, + }, + ], + }, + }); + policyOneName = results[0].name; + results = await client.createAlertPolicy({ + name: client.projectPath(projectId), + alertPolicy: { + displayName: 'second', + combiner: 1, + conditions: [ + { + displayName: 'Condition 2', + conditionAbsent: { + filter: `metric.type = "cloudfunctions.googleapis.com/function/execution_count"`, + aggregations: [ + { + alignmentPeriod: { + seconds: 60, + }, + perSeriesAligner: 1, + crossSeriesReducer: 0, + }, + ], + duration: { + seconds: 60, + }, + trigger: { + count: 1, + }, + }, + }, + ], + }, + }); + policyTwoName = results[0].name; + results = await channelClient.createNotificationChannel({ + name: channelClient.projectPath(projectId), + notificationChannel: { + displayName: 'Channel 1', + type: 'email', + labels: { + email_address: 'test@test.com', + }, + }, + }); + channelName = results[0].name; +}); + +function deletePolicies() { + return Promise.all([ + client.deleteAlertPolicy({ + name: policyOneName, + }), + client.deleteAlertPolicy({ + name: policyTwoName, + }), + ]); +} + +function deleteChannels() { + return Promise.all([ + channelClient.deleteNotificationChannel({ + name: channelName, + }), + ]); +} + +test.after.always(async () => { + await deletePolicies(); + // has to be done after policies are deleted + await deleteChannels(); +}); + +test.serial(`should backup all policies`, async t => { + const results = await tools.spawnAsyncWithIO( + `node`, + [`alerts.js`, `backup`, projectId], + cwd + ); + t.regex(results.output, /Saved policies to \.\/policies_backup.json/); + t.true(fs.existsSync(path.join(cwd, `policies_backup.json`))); + await client.deleteAlertPolicy({name: policyOneName}); +}); + +test.serial(`should restore policies`, async t => { + const results = await tools.spawnAsyncWithIO( + `node`, + [`alerts.js`, `restore`, projectId], + cwd + ); + t.regex(results.output, /Loading policies from .\/policies_backup.json/); + const nameRegexp = /projects\/[A-Za-z0-9-]+\/alertPolicies\/([\d]+)/gi; + const matches = results.output.match(nameRegexp); + t.true(Array.isArray(matches)); + t.is(matches.length, 2); + policyOneName = matches[0]; + policyTwoName = matches[1]; +}); + +test.serial(`should replace notification channels`, async t => { + const results = await tools.spawnAsyncWithIO( + `node`, + [`alerts.js`, `replace`, policyOneName, channelName], + cwd + ); + t.regex(results.output, /Updated projects\//); + t.true(results.output.includes(policyOneName)); +}); + +test.serial(`should disable policies`, async t => { + const results = await tools.spawnAsyncWithIO( + `node`, + [`alerts.js`, `disable`, projectId, `'display_name.size < 7'`], + cwd + ); + t.regex(results.output, /Disabled projects\//); + t.false(results.output.includes(policyOneName)); + t.true(results.output.includes(policyTwoName)); +}); + +test.serial(`should enable policies`, async t => { + const results = await tools.spawnAsyncWithIO( + `node`, + [`alerts.js`, `enable`, projectId, `'display_name.size < 7'`], + cwd + ); + t.regex(results.output, /Enabled projects\//); + t.false(results.output.includes(policyOneName)); + t.true(results.output.includes(policyTwoName)); +});