serverless-newrelic-lambda-layers
Advanced tools
Comparing version 0.1.20 to 0.2.0
@@ -18,2 +18,5 @@ "use strict"; | ||
const util = require("util"); | ||
const api_1 = require("./api"); | ||
const integration_1 = require("./integration"); | ||
const utils_1 = require("./utils"); | ||
const DEFAULT_FILTER_PATTERNS = [ | ||
@@ -30,2 +33,3 @@ "REPORT", | ||
this.awsProvider = this.serverless.getProvider("aws"); | ||
this.region = _.get(this.serverless.service, "provider.region", "us-east-1"); | ||
this.hooks = this.shouldSkipPlugin() | ||
@@ -37,2 +41,3 @@ ? {} | ||
"after:package:createDeploymentArtifacts": this.cleanup.bind(this), | ||
"before:deploy:deploy": this.integration.check.bind(this), | ||
"before:deploy:function:packageFunction": this.run.bind(this), | ||
@@ -46,2 +51,5 @@ "before:package:createDeploymentArtifacts": this.run.bind(this), | ||
} | ||
get integration() { | ||
return new integration_1.default(this); | ||
} | ||
get stage() { | ||
@@ -147,4 +155,3 @@ return ((this.options && this.options.stage) || | ||
this.serverless.cli.log(`Adding NewRelic layer to ${funcName}`); | ||
const region = _.get(this.serverless.service, "provider.region"); | ||
if (!region) { | ||
if (!this.region) { | ||
this.serverless.cli.log("No AWS region specified for NewRelic layer; skipping."); | ||
@@ -176,3 +183,3 @@ return; | ||
? this.config.layerArn | ||
: yield this.getLayerArn(runtime, region); | ||
: yield this.getLayerArn(runtime); | ||
const newRelicLayers = layers.filter(layer => typeof layer === "string" && layer.match(layerArn)); | ||
@@ -261,6 +268,6 @@ // Note: This is if the user specifies a layer in their serverless.yml | ||
} | ||
getLayerArn(runtime, region) { | ||
getLayerArn(runtime) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
return util | ||
.promisify(request)(`https://${region}.layers.newrelic-external.com/get-layers?CompatibleRuntime=${runtime}`) | ||
.promisify(request)(`https://${this.region}.layers.newrelic-external.com/get-layers?CompatibleRuntime=${runtime}`) | ||
.then(response => { | ||
@@ -320,3 +327,3 @@ const awsResp = JSON.parse(response.body); | ||
let destinationArn; | ||
const { logIngestionFunctionName = "newrelic-log-ingestion" } = this.config; | ||
const { logIngestionFunctionName = "newrelic-log-ingestion", apiKey } = this.config; | ||
try { | ||
@@ -327,6 +334,12 @@ destinationArn = yield this.getDestinationArn(logIngestionFunctionName); | ||
this.serverless.cli.log(`Could not find a \`${logIngestionFunctionName}\` function installed.`); | ||
this.serverless.cli.log("Please follow the setup instructions here: https://docs.newrelic.com/docs/serverless-function-monitoring/aws-lambda-monitoring/get-started/enable-new-relic-monitoring-aws-lambda#enable-process"); | ||
this.serverless.cli.log("Details about setup requirements are available here: https://docs.newrelic.com/docs/serverless-function-monitoring/aws-lambda-monitoring/get-started/enable-new-relic-monitoring-aws-lambda#enable-process"); | ||
if (err.providerError) { | ||
this.serverless.cli.log(err.providerError.message); | ||
} | ||
if (!apiKey) { | ||
this.serverless.cli.log("Unable to create newrelic-log-ingestion because New Relic API key not configured."); | ||
return; | ||
} | ||
this.serverless.cli.log(`creating required newrelic-log-ingestion function in region ${this.region}`); | ||
this.addLogIngestionFunction(); | ||
return; | ||
@@ -373,2 +386,88 @@ } | ||
} | ||
addLogIngestionFunction() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const templateUrl = yield this.getSarTemplate(); | ||
if (!templateUrl) { | ||
this.serverless.cli.log("Unable to create newRelic-log-ingestion without sar template."); | ||
return; | ||
} | ||
try { | ||
const mode = "CREATE"; | ||
const stackName = "NewRelic-log-ingestion"; | ||
const changeSetName = `${stackName}-${mode}-${Date.now()}`; | ||
const parameters = yield this.formatFunctionVariables(); | ||
const params = { | ||
Capabilities: ["CAPABILITY_IAM"], | ||
ChangeSetName: changeSetName, | ||
ChangeSetType: mode, | ||
Parameters: parameters, | ||
StackName: stackName, | ||
TemplateURL: templateUrl | ||
}; | ||
const { Id, StackId } = yield this.awsProvider.request("CloudFormation", "createChangeSet", params); | ||
this.serverless.cli.log("Waiting for change set creation to complete, this may take a minute..."); | ||
utils_1.waitForStatus({ | ||
awsMethod: "describeChangeSet", | ||
callbackMethod: () => this.executeChangeSet(Id, StackId), | ||
methodParams: { ChangeSetName: Id }, | ||
statusPath: "Status" | ||
}, this); | ||
} | ||
catch (err) { | ||
this.serverless.cli.log("Unable to create newrelic-log-ingestion function. Please verify that required environment variables have been set."); | ||
} | ||
}); | ||
} | ||
formatFunctionVariables() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const { logEnabled, apiKey, accountId } = this.config; | ||
const userData = yield api_1.nerdgraphFetch(apiKey, this.region, api_1.fetchLicenseKey(accountId)); | ||
const { licenseKey } = _.get(userData, "data.actor.account", null); | ||
const loggingVar = logEnabled ? "True" : "False"; | ||
const parameters = [ | ||
{ | ||
ParameterKey: "NRLoggingEnabled", | ||
ParameterValue: `${loggingVar}` | ||
}, | ||
{ | ||
ParameterKey: "NRLicenseKey", | ||
ParameterValue: `${licenseKey}` | ||
} | ||
]; | ||
return parameters; | ||
}); | ||
} | ||
getSarTemplate() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
try { | ||
const data = yield this.awsProvider.request("ServerlessApplicationRepository", "createCloudFormationTemplate", { | ||
ApplicationId: "arn:aws:serverlessrepo:us-east-1:463657938898:applications/NewRelic-log-ingestion" | ||
}); | ||
const { TemplateUrl } = data; | ||
return TemplateUrl; | ||
} | ||
catch (err) { | ||
this.serverless.cli.log(`Something went wrong while fetching the sar template: ${err}`); | ||
} | ||
}); | ||
} | ||
executeChangeSet(changeSetName, stackId) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
try { | ||
yield this.awsProvider.request("CloudFormation", "executeChangeSet", { | ||
ChangeSetName: changeSetName | ||
}); | ||
this.serverless.cli.log("Waiting for newrelic-log-ingestion install to complete, this may take a minute..."); | ||
utils_1.waitForStatus({ | ||
awsMethod: "describeStacks", | ||
callbackMethod: () => this.addLogSubscriptions(), | ||
methodParams: { StackName: stackId }, | ||
statusPath: "Stacks[0].StackStatus" | ||
}, this); | ||
} | ||
catch (changeSetErr) { | ||
this.serverless.cli.log(`Something went wrong while executing the change set: ${changeSetErr}`); | ||
} | ||
}); | ||
} | ||
describeSubscriptionFilters(funcName) { | ||
@@ -375,0 +474,0 @@ return __awaiter(this, void 0, void 0, function* () { |
{ | ||
"name": "serverless-newrelic-lambda-layers", | ||
"version": "0.1.20", | ||
"version": "0.2.0", | ||
"description": "Serverless plugin for NewRelic APM AWS Lambda layers.", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
@@ -9,6 +9,6 @@ # serverless-newrelic-lambda-layers | ||
- [serverless](https://github.com/serverless/serverless) >= 1.34.0 | ||
- Set up the [New Relic AWS Integration](https://docs.newrelic.com/docs/serverless-function-monitoring/aws-lambda-monitoring/get-started/enable-new-relic-monitoring-aws-lambda#enable-process) (only the `newrelic-lambda integrations install` step is required) | ||
## Features | ||
- Installs and configures the New Relic AWS Integration | ||
- Supports Node.js and Python runtimes (more runtimes to come) | ||
@@ -41,5 +41,6 @@ - No code change required to enable New Relic | ||
If you don't yet have a New Relic account, [sign up here](https://newrelic.com/products/serverless-aws-lambda). | ||
Then set up the [New Relic AWS Integration](https://docs.newrelic.com/docs/serverless-function-monitoring/aws-lambda-monitoring/get-started/enable-new-relic-monitoring-aws-lambda#enable-process) (only the `set-up-lambda-integration` step is required). | ||
Get your [New Relic Account ID](https://docs.newrelic.com/docs/accounts/install-new-relic/account-setup/account-id) and plug it into your `serverless.yml`: | ||
Grab your [New Relic Account ID](https://docs.newrelic.com/docs/accounts/install-new-relic/account-setup/account-id), | ||
your [New Relic Personal API Key](https://docs.newrelic.com/docs/apis/get-started/intro-apis/types-new-relic-api-keys#personal-api-key) | ||
and plug them into your `serverless.yml`: | ||
@@ -50,2 +51,3 @@ ```yaml | ||
accountId: your-new-relic-account-id-here | ||
apiKey: your-new-relic-personal-api-key-here | ||
``` | ||
@@ -84,2 +86,23 @@ | ||
#### `apiKey` (required) | ||
Your [New Relic Personal API Key](https://docs.newrelic.com/docs/apis/get-started/intro-apis/types-new-relic-api-keys#personal-api-key). | ||
```yaml | ||
custom: | ||
newRelic: | ||
apiKey: your-api-key-here | ||
``` | ||
#### `linkedAccount` (optional) | ||
A label for the New Relic Linked Account. This is how this integration will | ||
appear in New Relic. If not set, it will default to "New Relic Lambda Integration - | ||
<AWS ACcount ID>". | ||
```yaml | ||
custom: | ||
newRelic: | ||
linkedAccount: your-linked-account-name | ||
#### `trustedAccountKey` (optional) | ||
@@ -92,3 +115,2 @@ | ||
newRelic: | ||
accountId: your-sub-account-id | ||
trustedAccountKey: your-parent-account-id | ||
@@ -112,2 +134,12 @@ ``` | ||
#### `enableIntegration` (optional) | ||
Allows the creation of New Relic aws cloud integration when absent. Defaults to `false` | ||
```yaml | ||
custom: | ||
newRelic: | ||
enableIntegration: true | ||
``` | ||
#### `logLevel` (optional) | ||
@@ -132,5 +164,5 @@ | ||
#### `stages` (optional) | ||
#### `customRolePolicy` (optional) | ||
An array of stages that the plugin will be included for. If this key is not specified then all stages will be included. | ||
Specify an alternative IAM role policy ARN for this integration here if you do not want to use the default role policy. | ||
@@ -140,3 +172,9 @@ ```yaml | ||
newRelic: | ||
stages: | ||
customRolePolicy: your-custom-role-policy-arn | ||
``` | ||
#### `stages` (optional) | ||
An array of stages that the plugin will be included for. If this key is not specified then all stages will be included. | ||
stages: | ||
- prod | ||
@@ -143,0 +181,0 @@ ``` |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
55196
7
770
295
2
1