This repository was archived by the owner on May 18, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
LogDNA and Eventstream support #8
Open
jagdishkumar1
wants to merge
8
commits into
ibm-cloud-security:master
Choose a base branch
from
jagdishkumar1:logDNA-Kafka
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
e6b8aad
add support for logDNA and Event stream
jagdishkumar1 60e93cf
update eventstream support
jagdishkumar1 d5d6d7e
update eventstream support
jagdishkumar1 192122b
Merge branch 'logDNA-Kafka' of https://github.com/jagdishkumar1/secur…
jagdishkumar1 85c5949
Merge branch 'logDNA-Kafka' of https://github.com/jagdishkumar1/secur…
jagdishkumar1 a1f7083
Merge branch 'logDNA-Kafka' of https://github.com/jagdishkumar1/secur…
jagdishkumar1 04efcd0
Merge branch 'logDNA-Kafka' of https://github.com/jagdishkumar1/secur…
jagdishkumar1 8e4d1e3
Merge branch 'logDNA-Kafka' of https://github.com/jagdishkumar1/secur…
jagdishkumar1 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| { | ||
| "plugins": [ | ||
| "@babel/plugin-syntax-bigint" | ||
| ] | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,9 +1,9 @@ | ||
| const jwt = require("jsonwebtoken"); | ||
| const axios = require("axios"); | ||
| var log4js = require("log4js"); | ||
| var logger = log4js.getLogger(); | ||
| const date = require('date-and-time'); | ||
| var logger = log4js.getLogger('security-advisor-notification-webhook'); | ||
| logger.level = "info"; | ||
| const request = require("request"); | ||
|
|
||
| const webhookInternalErrorResponse = { err: "WebHook Internal Error." }; | ||
|
|
||
|
|
@@ -29,9 +29,8 @@ async function downloadPublicKey(accessToken, accountId, params) { | |
| } | ||
| }; | ||
|
|
||
| const url = `${ | ||
| params.notificationChannelUrl | ||
| }/v1/${accountId}/notifications/public_key`; | ||
| const url = `${params.notificationChannelUrl | ||
| }/v1/${accountId}/notifications/public_key`; | ||
| const response = await axios.get(url, config); | ||
| logger.info(`Downloaded public key for account ${accountId}`); | ||
| return response.data.publicKey; | ||
|
|
@@ -45,16 +44,100 @@ async function downloadPublicKey(accessToken, accountId, params) { | |
| } | ||
| } | ||
|
|
||
| async function sendToLogDNA(finding, params) { | ||
| try { | ||
| const basicAuth = Buffer.from(`${params.logDNAIngestionKey}:`).toString('base64') | ||
| const config = { | ||
| headers: { | ||
| "Content-Type": "application/json", | ||
| Accept: "application/json", | ||
| Authorization: `Basic ${basicAuth}` | ||
| } | ||
| }; | ||
| const body = { | ||
| "lines": [ | ||
| { | ||
| "timestamp": date.format(new Date(), 'YYYY-MM-DDTHH:mm:ss.SSZ', true), | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Perhaps we can just use |
||
| "line": JSON.stringify(finding), | ||
| "app": "cloud function", | ||
| "level": "INFO", | ||
| "meta": { | ||
| "labels": "IBM Security Advisor" | ||
| } | ||
| } | ||
| ] | ||
| } | ||
| const url = `${params.logDNAEndpoint}/logs/ingest?hostname=security-advisor-notification-webhook&tags=security-advisor&now=${Date.now()}` | ||
|
|
||
| await axios.post(url, body, config); | ||
| } catch (err) { | ||
| logger.error( | ||
| `Error while sending finding ${finding["id"] | ||
| } to logDNA : ${err}` | ||
| ); | ||
| throw err; | ||
| } | ||
| } | ||
|
|
||
| async function sendToEventstream(finding, params) { | ||
| const { Kafka } = require('kafkajs'); | ||
| const topic = params.kafkaTopic; | ||
| const brokers = params.kafkaMetadataBrokerList.split(',') | ||
| const kafka = new Kafka({ | ||
| clientId: 'security-advisor-notification-webhook', | ||
| kafka_topic: topic, | ||
| brokers: brokers, | ||
| sasl: { | ||
| mechanism: 'plain', | ||
| username: params.kafkaSaslUsername, | ||
| password: params.kafkaSaslPassword | ||
| }, | ||
| ssl: true, | ||
| connectionTimeout: 3000, | ||
| authenticationTimeout: 1000, | ||
| reauthenticationThreshold: 10000, | ||
| }); | ||
| // 2.Creating Kafka Producer | ||
| const producer = kafka.producer(); | ||
| const runProducer = async () => { | ||
| // 3.Connecting producer to kafka broker. | ||
| try { | ||
| await producer.connect() | ||
| await producer.send({ | ||
| topic: topic, | ||
| messages: | ||
| [{ value: JSON.stringify(finding) }], | ||
| }) | ||
| await producer.disconnect() | ||
| } catch (err) { | ||
| logger.error( | ||
| `Error while sending finding ${finding["id"] | ||
| } to Eventstream : ${err}` | ||
| ); | ||
| throw err; | ||
| } | ||
| } | ||
| try { | ||
| await runProducer() | ||
| logger.info(`Finding ${finding["id"]} is published to '${topic}'`); | ||
| } catch (err) { | ||
| logger.error( | ||
| `Error while sending finding ${finding["id"] | ||
| } to Eventstream : ${err}` | ||
| ); | ||
| throw err; | ||
| } | ||
| } | ||
|
|
||
| async function createGitHubIssue(finding, params) { | ||
| try { | ||
| var issueDesc = `**Source**: ${finding["payload"]["reported_by"]["title"]}\n`; | ||
| issueDesc = issueDesc + `**Finding**: ${finding["id"]}\n`; | ||
| issueDesc = issueDesc + `**Severity**: ${finding["severity"]}\n`; | ||
| issueDesc = issueDesc + `[View in Security Advisor Dashboard](${finding["issuer-url"]})\n`; | ||
| var body = { | ||
| title: `${ | ||
| finding["severity"] | ||
| } severity finding reported by IBM Security Advisor`, | ||
| title: `${finding["severity"] | ||
| } severity finding reported by IBM Security Advisor`, | ||
| body: issueDesc, | ||
| labels: ["IBM Security Advisor"] | ||
| }; | ||
|
|
@@ -70,8 +153,7 @@ async function createGitHubIssue(finding, params) { | |
| const response = await axios.post(params.GITHUB_API_URL, body, config); | ||
| } catch (err) { | ||
| logger.error( | ||
| `Error while creating GitHub issue for finding ${ | ||
| finding["id"] | ||
| `Error while creating GitHub issue for finding ${finding["id"] | ||
| }: ${JSON.stringify(err)}` | ||
| ); | ||
| throw err; | ||
|
|
@@ -89,7 +171,7 @@ async function sendToSlack(finding, params) { | |
| attachments: [ | ||
| { | ||
| color: "#FFD300", | ||
| text: "```" + messageDesc + "```", | ||
| text: "```" + messageDesc + "```", | ||
| mrkdwn_in: ["text"], | ||
| actions: [ | ||
| { | ||
|
|
@@ -172,7 +254,7 @@ async function main(params) { | |
| ); | ||
| await sendToSlack(finding, params); | ||
| } catch (err) { | ||
| logger.error(`Slack error : JSON.stringify(err)`); | ||
| logger.error(`Slack error : ${JSON.stringify(err)}`); | ||
| return { err: "Couldn't notify slack" }; | ||
| } | ||
| } else if (severity === "high" || severity === "medium") { | ||
|
|
@@ -188,6 +270,36 @@ async function main(params) { | |
| return { err: "Couldn't create github issue" }; | ||
| } | ||
| } | ||
|
|
||
| if (params.sendToLogDNA === "True") { | ||
| try { | ||
| logger.info( | ||
| `Received a finding ${finding["id"]}. Sending to logDNA.` | ||
| ); | ||
| await sendToLogDNA(finding, params); | ||
| logger.info( | ||
| `Successfully send finding ${finding["id"]} to logDNA.` | ||
| ); | ||
| } catch (err) { | ||
| logger.error(`logDNA error : ${err}`); | ||
| return { err: "Couldn't send to logDNA" }; | ||
| } | ||
| } | ||
|
|
||
| if (params.sendToEventstream === "True") { | ||
| try { | ||
| logger.info( | ||
| `Received a finding ${finding["id"]}. Sending to Event stream.` | ||
| ); | ||
| await sendToEventstream(finding, params); | ||
| logger.info( | ||
| `Successfully send finding ${finding["id"]} to Event stream.` | ||
| ); | ||
| } catch (err) { | ||
| logger.error(`Eventstream error : ${err}`); | ||
| return { err: "Couldn't send to Eventstream" }; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| exports.main = main; | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like devDependencies.