Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[lambda][flare] Send minimal Lambda config data to Datadog #924

Merged

Conversation

nhulston
Copy link
Contributor

@nhulston nhulston commented Jun 9, 2023

What and why?

This PR adds functionality to the datadog-ci lambda flare command to automatically collect useful information from customers to help Datadog support resolve customer issues. This PR only adds functionality for getting and sending AWS Lambda function configuration for a single Lambda function/region to the support staff.

Future PRs aim to:

  • Support multiple Lambda functions/regions
  • Gather AWS CloudWatch logs
  • Add an interactive mode
  • Enable support ticket creation via the command
  • And more
Screenshot 2023-06-22 at 11 07 36 AM

How?

An example command would be lambda flare -f function-name -r us-east-1 -c 1234567 -e [email protected]

This PR allows sending function configuration to the support staff through several steps:

  1. Checks for required flags and environment variables: Datadog API key, AWS lambda function name or ARN, Datadog case ID (to send the config file to), and customer email
  2. Accepts the following flags: --dry, --function, --region, --case-id, --email (and their shorthands -d, -f, -r, -c, -e). The --dry flag enables a mode where the config.json is printed but not saved as a file or sent.
Screenshot 2023-06-22 at 11 10 03 AM
  1. Fetches AWS credentials using the getAWSCredentials() or requestAWSCredentials() functions:
    export const getAWSCredentials = async () => {
    const provider = fromNodeProviderChain()
    try {
    const credentials = await provider()
    return credentials
    } catch (err) {
    if (err instanceof Error) {
    if (err.name === CredentialsProviderError.name) {
    return undefined
    }
    throw Error(`Couldn't fetch AWS credentials. ${err.message}`)
    }
    }
    }
    and https:/DataDog/datadog-ci/blob/01ffb226b154935c71e4618d5a53e24414c1971a/src/commands/lambda/prompt.ts#L215-L22
  2. Retrieves and prints Lambda function config from AWS using getLambdaFunctionConfig():
    /**
    * Call the aws-sdk Lambda api to get a Function given
    * an ARN and then return its Configuration.
    *
    * @param lambdaClient an instance of LambdaClient.
    * @param functionARN a string, can be Function ARN, Partial ARN, or a Function Name.
    * @returns the Lambda FunctionConfiguration of the given ARN.
    */
    export const getLambdaFunctionConfig = async (
    lambdaClient: LambdaClient,
    functionARN: string
    ): Promise<LFunctionConfiguration> => {
    const params: GetFunctionCommandInput = {
    FunctionName: functionARN,
    }
    const command = new GetFunctionCommand(params)
    const response = await lambdaClient.send(command)
    // AWS typescript API is slightly mistyped, adds undefineds where
    // there shouldn't be.
    const config = response.Configuration!
    return config
    }
  3. Saves the config file in .datadog-ci/config.json using the fs package
  4. Zips the .datadog-ci folder using the jszip package. Future PRs will save multiple files, so jszip is required to zip an entire directory
  5. Sends the zipped file to Datadog support via a POST request defined here: https:/DataDog/dogweb/pull/96288
  6. Deletes the zipped file and folder contents after being sent to support

These changes provide a robust foundation for future PRs, ensuring efficient implementation of additional features.

Review checklist

  • Feature or bugfix MUST have appropriate tests (unit, integration)

@nhulston nhulston marked this pull request as ready for review June 9, 2023 15:58
@nhulston nhulston requested a review from a team as a code owner June 9, 2023 15:58
@datadog-datadog-prod-us1
Copy link

datadog-datadog-prod-us1 bot commented Jun 9, 2023

Datadog Report

Branch report: nicholas.hulston/serverless-flare/flare-subcommand
Commit report: 1bb8b07

datadog-ci-tests: 0 Failed, 0 New Flaky, 663 Passed, 0 Skipped, 48.22s Wall Time

Copy link
Contributor

@duncanista duncanista left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couple comments

@duncanista duncanista changed the title [lambda] [flare] Create lambda flare subcommands [lambda][flare] Add minimal command options Jun 9, 2023
@nhulston nhulston requested a review from duncanista June 9, 2023 19:27
Copy link
Contributor

@duncanista duncanista left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some comments

src/commands/lambda/flare.ts Outdated Show resolved Hide resolved
src/commands/lambda/flare-command-validator.ts Outdated Show resolved Hide resolved
src/commands/lambda/flare-command-validator.ts Outdated Show resolved Hide resolved
src/commands/lambda/flare-command-validator.ts Outdated Show resolved Hide resolved
src/commands/lambda/flare-command-validator.ts Outdated Show resolved Hide resolved
src/commands/lambda/flare-command-validator.ts Outdated Show resolved Hide resolved
src/commands/lambda/renderers/flare-renderer.ts Outdated Show resolved Hide resolved
src/commands/lambda/flare-command-validator.ts Outdated Show resolved Hide resolved
@nhulston nhulston changed the title [lambda][flare] Add minimal command options [lambda][flare] Add command flags, gather single function configuration, send to case ID Jun 13, 2023
@nhulston nhulston requested a review from a team as a code owner June 13, 2023 18:25
@nhulston nhulston marked this pull request as draft June 13, 2023 18:25
package.json Show resolved Hide resolved
@nhulston nhulston changed the title [lambda][flare] Add command flags, gather single function configuration, send to case ID [lambda][flare] Send lambda function configuration to support team Jun 13, 2023
src/__mocks__/util.js Outdated Show resolved Hide resolved
Copy link
Contributor

@juan-fernandez juan-fernandez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I lack the context for reviewing the lambda bit but do we need jszip? Have we tried using zlib?


const {version} = require('../../../package.json')

const ENDPOINT_URL = 'https://datad0g.com/api/ui/support/serverless/flare'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we want to hardcode a staging URL like this?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @juan-fernandez, we will hard code it for staging in the meantime. We will not merge this to the main branch until we have the right endpoint merged in production.

We will bring another PR to update this to the user specific site endpoint in the future, wdyt?

const data = fs.readFileSync(filePath, 'utf8')
const zip = new JSZip()
zip.file(FUNCTION_CONFIG_FILE_NAME, data)
const content = await zip.generateAsync({type: 'nodebuffer'})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

couldn't we use zlib that is native? We wouldn't need a new dependency then.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the review, I will look into using zlib instead

Copy link
Contributor Author

@nhulston nhulston Jun 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @juan-fernandez
Looks like zlib only supports zipping single files. While this would work for this PR, we do plan on zipping multiple files in the near future, so we would eventually need a new dependency like jszip.

What do you think?

Edit: I meant jszip not fszip!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nhulston do you mean jszip?

@juan-fernandez I'd normally go for the zlib approach too, when I researched on this, it seemed that we needed more packages to compress folders (tar and fstream). By using zlib and its dependencies for our use case, previously mentioned, we would be using 550~600 kB less than if we used jszip.

It seems that change of implementation might be trivial. But of course, this could be refactored in the future if package size is a problem. This would also not be merged directly into main since our working branch serverless-flare is still a WIP before its first release.

What do you think @juan-fernandez?

Copy link
Contributor

@duncanista duncanista left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great first PR!

@duncanista duncanista added the serverless Related to [lambda, stepfunctions, cloud-run] label Jun 22, 2023
@nhulston nhulston merged commit 174bccd into serverless-flare Jun 22, 2023
@nhulston nhulston deleted the nicholas.hulston/serverless-flare/flare-subcommand branch June 22, 2023 15:22
nhulston added a commit that referenced this pull request Jun 22, 2023
duncanista pushed a commit that referenced this pull request Jun 30, 2023
* Create and validate flare flags
* Write config to file and zip it
* - Send zip to Datadog when not in dry run
* Change zip method to use the `jszip` package for compatability on Windows, Mac, and Linux
* Add `jszip` copyright
* - Move constant endpoints
- Remove redundant try/catch on `fs.createReadStream` since the higher-level function `execute` handles the error
- Remove redundant `.then()` since we already use `await`
* Get CLI version programmatically and set as `operator_version`
* Rename `operator_version` to `datadog_ci_version`
* Code review refactoring
* Create thorough tests
@duncanista duncanista mentioned this pull request Jul 12, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
serverless Related to [lambda, stepfunctions, cloud-run]
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants