Skip to content

Commit

Permalink
feat(monitoring): ability to use custom script
Browse files Browse the repository at this point in the history
  • Loading branch information
rofe committed Jan 30, 2020
1 parent eabcd8d commit a3328df
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 9 deletions.
7 changes: 6 additions & 1 deletion .circleci/orbs/helix-post-deploy/orb.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ commands:
type: string
default: ""
description: The URL to monitor in New Relic
newrelic_script:
type: string
default: ""
description: The path to the custom monitor script to use
newrelic_group_policy:
type: string
default: ""
Expand Down Expand Up @@ -86,6 +90,7 @@ commands:
nrAuth="<< parameters.newrelic_auth >>"
nrName="<< parameters.newrelic_name >>"
nrURL="<< parameters.newrelic_url >>"
nrScript="<< parameters.newrelic_script >>"
nrGroupPolicy="<< parameters.newrelic_group_policy >>"
spAuth="<< parameters.statuspage_auth >>"
spPageID="<< parameters.statuspage_page_id >>"
Expand All @@ -103,4 +108,4 @@ commands:
actionVersion=`node -e "console.log(require('./package.json').version.match(/^[0-9]+.[0-9]+/)[0])"`
nrURL="https://adobeioruntime.net/api/v1/web/${actionNS}/${actionPackage}/${actionName}@v${actionVersion}/_status_check/healthcheck.json"
fi
node ${toolPath}/newrelic setup ${nrURL} ${spEmail} ${nrName:+--name "${nrName}"} ${nrGroupPolicy:+--group_policy "${nrGroupPolicy}"}
node ${toolPath}/newrelic setup ${nrURL} ${spEmail} ${nrName:+--name "${nrName}"} ${nrScript:+--script "${nrScript}"} ${nrGroupPolicy:+--group_policy "${nrGroupPolicy}"}
9 changes: 7 additions & 2 deletions src/newrelic/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,17 +58,22 @@ class CLI {
type: 'string',
describe: 'The name of a common policy to add the monitor to',
required: false,
})
.option('script', {
type: 'string',
describe: 'The path to the custom monitor script to use',
required: false,
});
}

return yargs
.scriptName('newrelic')
.usage('$0 <cmd>')
.command('setup url email', 'Create or update a New Relic setup', (y) => baseargs(y), async ({
auth, name, url, email, group_policy,
auth, name, url, email, group_policy, script,
}) => {
await updateOrCreatePolicies(auth, name, group_policy,
await updateOrCreateMonitor(auth, name, url),
await updateOrCreateMonitor(auth, name, url, script),
email ? await reuseOrCreateChannel(auth, name, email) : null);
console.log('done.');
})
Expand Down
10 changes: 5 additions & 5 deletions src/newrelic/synthetics.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ async function getMonitors(auth, monitorname) {
}
}

async function updateMonitor(auth, monitor, url) {
async function updateMonitor(auth, monitor, url, script) {
console.log('Updating locations for monitor', monitor.name);
try {
await request.patch(`https://synthetics.newrelic.com/synthetics/api/v3/monitors/${monitor.id}`, {
Expand All @@ -94,7 +94,7 @@ async function updateMonitor(auth, monitor, url) {
console.log('Updating script for monitor', monitor.name);

const scriptText = Buffer.from(fs
.readFileSync(path.resolve(__dirname, 'monitor_script.js'))
.readFileSync(script || path.resolve(__dirname, 'monitor_script.js'))
.toString()
.replace('$$$URL$$$', url)
.replace('$$$NS$$$', getNS(url)))
Expand All @@ -114,12 +114,12 @@ async function updateMonitor(auth, monitor, url) {
}
}

async function updateOrCreateMonitor(auth, name, url) {
async function updateOrCreateMonitor(auth, name, url, script) {
const [monitor] = await getMonitors(auth, name);

if (monitor) {
// update
await updateMonitor(auth, monitor, url);
await updateMonitor(auth, monitor, url, script);
} else {
// create
console.log('Creating monitor', name);
Expand All @@ -138,7 +138,7 @@ async function updateOrCreateMonitor(auth, name, url) {
slaThreshold: MONITOR_THRESHOLD,
},
});
return await updateOrCreateMonitor(auth, name, url);
return await updateOrCreateMonitor(auth, name, url, script);
} catch (e) {
console.error('Monitor creation failed:', e.message);
process.exit(1);
Expand Down
18 changes: 18 additions & 0 deletions test/fixtures/monitor_script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* Copyright 2019 Adobe. All rights reserved.
* This file is licensed to you 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 REPRESENTATIONS
* OF ANY KIND, either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/
/* eslint-disable no-console */
/* global $http */

$http.get('$$$URL$$$',
(err, response, body) => {
console.log(body);
});
53 changes: 52 additions & 1 deletion test/testNewrelic.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ const assert = require('assert');
const nock = require('nock');
const shell = require('shelljs');
const sinon = require('sinon');
const fs = require('fs');
const path = require('path');

const NewRelic = require('../src/newrelic/cli');
const {
Expand All @@ -35,14 +37,15 @@ const {
const { getTimedPromise } = require('./utils');

function buildArgs({
cmd, auth, url, email, name, groupPolicy,
cmd, auth, url, email, name, groupPolicy, script,
} = {}) {
const args = [];
if (cmd) args.push(cmd);
if (url) args.push(url);
if (email) args.push(email);
if (auth) args.push('--auth', auth);
if (name) args.push('--name', `"${name}"`);
if (script) args.push('--script', `"${script}"`);
if (groupPolicy) args.push('--group_policy', `"${groupPolicy}"`);
return args;
}
Expand Down Expand Up @@ -70,6 +73,7 @@ describe('Testing newrelic', () => {
const namePrefix = 'Test Service ';
const email = 'component+abcdef@notifications.statuspage.io';
const groupPolicy = 'Test Group Policy';
const script = path.resolve(__dirname, './fixtures/monitor_script.js');
const testMonitor = {
id: '0000',
frequency: MONITOR_FREQUENCY,
Expand Down Expand Up @@ -365,6 +369,53 @@ describe('Testing newrelic', () => {
]));
}).timeout(5000);

it('updates existing monitor with custom setup', async () => {
const expectedPayload = fs.readFileSync(path.resolve(__dirname, './fixtures/monitor_script.js'))
.toString()
.replace('$$$URL$$$', url);
let ok = false;

// synthetics API
nock('https://synthetics.newrelic.com')
.get(/.*/)
.reply(200, () => JSON.stringify({ count: 1, monitors: [testMonitor] }))
.patch(`/synthetics/api/v3/monitors/${testMonitor.id}`)
.reply(204, () => JSON.stringify(testMonitor))
// Updating script for monitor
.put(`/synthetics/api/v3/monitors/${testMonitor.id}/script`)
.reply(204, (uri, body) => {
ok = Buffer.from(body.scriptText, 'base64').toString() === expectedPayload;
return JSON.stringify(testMonitor);
});

// alerts API
nock('https://api.newrelic.com')
.get('/v2/alerts_channels.json')
.reply(200, () => JSON.stringify({ channels: [testChannel] }))
.get('/v2/alerts_policies.json')
.reply(200, () => JSON.stringify({ policies: [testPolicy] }))
.put('/v2/alerts_policy_channels.json')
.reply(200, () => JSON.stringify({ policy: testPolicy }))
.get('/v2/alerts_policies.json')
.reply(200, () => JSON.stringify({ policies: [testGroupPolicy] }))
.get(`/v2/alerts_location_failure_conditions/policies/${testPolicy.id}.json`)
.reply(200, () => JSON.stringify({ location_failure_conditions: [testExistingCondition] }))
.get(`/v2/alerts_location_failure_conditions/policies/${testGroupPolicy.id}.json`)
.reply(200, () => JSON.stringify({ location_failure_conditions: [testExistingCondition] }));

await run({
cmd,
url,
email,
auth,
name,
script,
groupPolicy,
});

assert.ok(await getTimedPromise(() => ok, 'Custom monitor script not used'));
}).timeout(5000);

it('uses environment variables', async () => {
process.env.NEWRELIC_AUTH = auth;

Expand Down

0 comments on commit a3328df

Please sign in to comment.