Skip to content

Commit

Permalink
Adding dd api governor (#58)
Browse files Browse the repository at this point in the history
* Adding a governor to prevent excessive Datadog calls

- Fixed a couple of spots I missed in the CJS migration
- Adding the Governor for HTTP posts to Datadog. It's quasi-configurable, but I haven't exposed the config yet.

* Update CHANGELOG.md
  • Loading branch information
manchicken authored Oct 2, 2023
1 parent d0cbd31 commit 8d7449d
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 2 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning].

## [Unreleased]

### Added

- Added a limit of ten Datadog calls per Workflow step

### Changed

- Updated dependencies
Expand Down
47 changes: 47 additions & 0 deletions __tests__/lib/governors.test.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Need to use inputs for some of our parameters
const core = require('@actions/core')

const {DatadogPostGovernor } = require('../../lib/governors')

describe('DatadogPostGovernor', () => {
test('init', () => {
DatadogPostGovernor.init()
expect(DatadogPostGovernor.state).toBe(0)
expect(DatadogPostGovernor.limit).toBe(10)
DatadogPostGovernor.init(42)
expect(DatadogPostGovernor.state).toBe(0)
expect(DatadogPostGovernor.limit).toBe(42)
})

test('increment', () => {
DatadogPostGovernor.init()
expect(DatadogPostGovernor.state).toBe(0)
expect(DatadogPostGovernor.limit).toBe(10)

DatadogPostGovernor.increment()
expect(DatadogPostGovernor.state).toBe(1)

DatadogPostGovernor.increment()
expect(DatadogPostGovernor.state).toBe(2)
})

test('enforcement', () => {
DatadogPostGovernor.init(3)
expect(DatadogPostGovernor.state).toBe(0)
expect(DatadogPostGovernor.limit).toBe(3)

DatadogPostGovernor.increment()
expect(DatadogPostGovernor.state).toBe(1)
expect(core.setFailed).not.toHaveBeenCalled()
DatadogPostGovernor.increment()
expect(DatadogPostGovernor.state).toBe(2)
expect(core.setFailed).not.toHaveBeenCalled()
DatadogPostGovernor.increment()
expect(DatadogPostGovernor.state).toBe(3)
expect(core.setFailed).not.toHaveBeenCalled()

DatadogPostGovernor.increment()
expect(DatadogPostGovernor.state).toBe(3)
expect(core.setFailed).toHaveBeenCalled()
})
})
File renamed without changes.
7 changes: 7 additions & 0 deletions index.cjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const core = require('@actions/core')
const { HttpClient } = require('@actions/http-client')

const { DatadogPostGovernor } = require('./lib/governors')
const { inputsToRegistryDocument } = require('./lib/input-to-registry-document')
const { validateDatadogHostname } = require('./lib/input-validation')
const { fetchAndApplyOrgRules } = require('./lib/org-rules')
Expand All @@ -11,6 +12,8 @@ const { fetchAndApplyOrgRules } = require('./lib/org-rules')
* @param {string} config - The config JSON string.
**/
const registerWithDataDog = async (apiKey, appKey, ddHost, configJsonStr) => {
DatadogPostGovernor.increment()

core.debug(`JSON: ${configJsonStr}`)
// Prep the auth
const client = new HttpClient(
Expand Down Expand Up @@ -42,6 +45,10 @@ const run = async (configs) => {
// Extract the API key for DataDog
const apiKey = core.getInput('datadog-key')
const appKey = core.getInput('datadog-app-key')

// Initialize the Post governor to help prevent excessive calls to Datadog
DatadogPostGovernor.init()

if (!apiKey || !appKey) {
return core.setFailed(
'Both `datadog-key` and `datadog-app-key` are required.',
Expand Down
3 changes: 2 additions & 1 deletion jest.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
"collectCoverage": true,
"coverageDirectory": "coverage",
"collectCoverageFrom": [
"**/lib/**/*.js"
"**/lib/**/*.js",
"**/lib/**/*.cjs"
],
"testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.c?js$",
"testPathIgnorePatterns": [
Expand Down
19 changes: 18 additions & 1 deletion lib/governors.cjs
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
const ddPostGovernor = {
const core = require('@actions/core')

const DatadogPostGovernor = {
state: undefined,
limit: undefined,
init: (limit = 10) => {
DatadogPostGovernor.limit = limit
DatadogPostGovernor.state = 0
},
increment: () => {
if (DatadogPostGovernor.state >= DatadogPostGovernor.limit) {
return core.setFailed(`Rate limit reached. Please do not exceed ${DatadogPostGovernor.limit} calls to Datadog in a single action.`)
}
DatadogPostGovernor.state += 1
},
}

module.exports = {
DatadogPostGovernor
}

0 comments on commit 8d7449d

Please sign in to comment.