Skip to content

Commit 4c96026

Browse files
amanenkhermanschaaferezrokah
authored
feat: Datadog plugin (#5096)
<!-- 🎉 Thank you for making CloudQuery awesome by submitting a PR 🎉 --> #### Summary closes #4794 <!-- Explain what problem this PR addresses --> <!-- Use the following steps to ensure your PR is ready to be reviewed - [ ] Read the [contribution guidelines](../blob/main/CONTRIBUTING.md) 🧑‍🎓 - [ ] Test locally on your own infrastructure - [ ] Run `go fmt` to format your code 🖊 - [ ] Lint your changes via `golangci-lint run` 🚨 (install golangci-lint [here](https://golangci-lint.run/usage/install/#local-installation)) - [ ] Update or add tests 🧪 - [ ] Ensure the status checks below are successful ✅ ---> Co-authored-by: Herman Schaaf <hermanschaaf@gmail.com> Co-authored-by: Erez Rokah <erezrokah@users.noreply.github.com>
1 parent a86e58d commit 4c96026

50 files changed

Lines changed: 2017 additions & 1 deletion

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/pr_labeler.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ cloudflare:
66
- plugins/source/cloudflare/**/*
77
digitalocean:
88
- plugins/source/digitalocean/**/*
9+
datadog:
10+
- plugins/source/datadog/**/*
911
fuzz:
1012
- plugins/source/fuzz/**/*
1113
gandi:

.github/styles/Vocab/Base/accept.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ subfolder
132132
recurse
133133
CCPA's
134134
bugfix
135+
Datadog
135136
nvm
136137
npm
137138
Gandi
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
name: Source Plugin Datadog Workflow
2+
3+
on:
4+
pull_request:
5+
paths:
6+
- "plugins/source/datadog/**"
7+
- ".github/workflows/source_datadog.yml"
8+
push:
9+
branches:
10+
- main
11+
paths:
12+
- "plugins/source/datadog/**"
13+
- ".github/workflows/source_datadog.yml"
14+
15+
jobs:
16+
resolve-runner:
17+
timeout-minutes: 5
18+
runs-on: ubuntu-latest
19+
outputs:
20+
runner: ${{ steps.resolve.outputs.runner }}
21+
steps:
22+
- name: Check if should use large runner
23+
id: large-runner
24+
# We want to speed runs on the main branch which prime the cache
25+
# We allow large runners only in this case to prevent forks from abusing them (it's enforced via runner groups access rules)
26+
# IF YOU WANT TO USE A LARGE RUNNER YOU NEED TO ADD THE WORKFLOW TO THE `CloudQuery releases` GROUP IN https://github.com/organizations/cloudquery/settings/actions/runner-groups
27+
if: github.event_name == 'push'
28+
run: |
29+
echo "runner=cloudquery-release-runner" >> $GITHUB_OUTPUT
30+
- name: Resolve runner
31+
id: resolve
32+
run: |
33+
RUNNER=${{ steps.large-runner.outputs.runner }}
34+
echo "runner=${RUNNER:-"ubuntu-latest"}" >> $GITHUB_OUTPUT
35+
plugins-source-datadog:
36+
timeout-minutes: 45
37+
name: "plugins/source/datadog"
38+
needs: [resolve-runner]
39+
runs-on: ${{ needs.resolve-runner.outputs.runner }}
40+
defaults:
41+
run:
42+
working-directory: ./plugins/source/datadog
43+
steps:
44+
- uses: actions/checkout@v3
45+
with:
46+
fetch-depth: 2
47+
- name: Set up Go 1.x
48+
uses: actions/setup-go@v3
49+
with:
50+
go-version-file: plugins/source/datadog/go.mod
51+
cache: true
52+
cache-dependency-path: plugins/source/datadog/go.sum
53+
- name: golangci-lint
54+
uses: golangci/golangci-lint-action@v3
55+
with:
56+
version: v1.50.1
57+
working-directory: plugins/source/datadog
58+
args: "--config ../../.golangci.yml"
59+
- name: Get dependencies
60+
run: go get -t -d ./...
61+
- name: Build
62+
run: go build .
63+
- name: Test
64+
run: make test
65+
- name: gen
66+
if: github.event_name == 'pull_request'
67+
run: make gen
68+
- name: Fail if generation updated files
69+
if: github.event_name == 'pull_request'
70+
run: test "$(git status -s | wc -l)" -eq 0
71+
validate-release:
72+
timeout-minutes: 45
73+
needs: [resolve-runner]
74+
runs-on: ${{ needs.resolve-runner.outputs.runner }}
75+
env:
76+
CGO_ENABLED: 0
77+
steps:
78+
- name: Checkout
79+
if: startsWith(github.head_ref, 'release-please--branches--main--components') || github.event_name == 'push'
80+
uses: actions/checkout@v3
81+
- uses: actions/cache@v3
82+
if: startsWith(github.head_ref, 'release-please--branches--main--components') || github.event_name == 'push'
83+
with:
84+
path: |
85+
~/.cache/go-build
86+
~/go/pkg/mod
87+
key: ${{ runner.os }}-go-1.19.3-release-cache-${{ hashFiles('plugins/source/datadog/go.sum') }}
88+
restore-keys: |
89+
${{ runner.os }}-go-1.19.3-release-cache-plugins-source-datadog
90+
- name: Set up Go
91+
if: startsWith(github.head_ref, 'release-please--branches--main--components') || github.event_name == 'push'
92+
uses: actions/setup-go@v3
93+
with:
94+
go-version-file: plugins/source/datadog/go.mod
95+
- name: Install GoReleaser
96+
if: startsWith(github.head_ref, 'release-please--branches--main--components') || github.event_name == 'push'
97+
uses: goreleaser/goreleaser-action@v3
98+
with:
99+
distribution: goreleaser-pro
100+
version: latest
101+
install-only: true
102+
- name: Run GoReleaser Dry-Run
103+
if: startsWith(github.head_ref, 'release-please--branches--main--components') || github.event_name == 'push'
104+
run: goreleaser release --snapshot --rm-dist --skip-validate --skip-publish --skip-sign -f ./plugins/source/datadog/.goreleaser.yaml
105+
env:
106+
GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }}

.github/workflows/wait_for_required_workflows.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ jobs:
4444
"plugins/source/azure",
4545
"plugins/source/cloudflare",
4646
"plugins/source/digitalocean",
47+
"plugins/source/datadog",
4748
"plugins/source/gandi",
4849
"plugins/source/gcp",
4950
"plugins/source/github",

plugins/source/datadog/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
datadog
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
variables:
2+
component: source/datadog
3+
binary: datadog
4+
5+
project_name: plugins/source/datadog
6+
7+
monorepo:
8+
tag_prefix: plugins-source-datadog-
9+
dir: plugins/source/datadog
10+
11+
includes:
12+
- from_file:
13+
# Relative to the directory Go Releaser is run from (which is the root of the repository)
14+
path: ./plugins/.goreleaser.yaml
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
repos:
2+
- repo: https://github.com/dnephin/pre-commit-golang
3+
rev: v0.5.0
4+
hooks:
5+
# - id: go-mod-tidy
6+
- id: golangci-lint

plugins/source/datadog/CHANGELOG.md

Whitespace-only changes.
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
# Datadog Source Plugin Contribution Guide
2+
3+
Thanks for contributing to CloudQuery! You are awesome. This document serves as a guide for adding new services and resources to the Datadog source plugin.
4+
5+
There are two steps to adding a new Datadog resource:
6+
7+
1. [Generate interfaces for the Datadog SDK function(s) that fetch the resource](#1-generate-interfaces-for-the-datadog-sdk-functions-that-fetch-the-resource)
8+
2. [Add a code generation recipe](#2-add-a-code-generation-recipe)
9+
10+
11+
## 1. Generate Interfaces for the Datadog SDK Function(s) that Fetch the Resource
12+
13+
### Before you Start
14+
15+
Inside the Datadog plugin directory, run:
16+
17+
```shell
18+
make install-tools
19+
```
20+
21+
This will install `mockgen` and any other tools necessary to complete the process.
22+
23+
### Generate the Service Interface
24+
25+
1. Check in [`client/services`](client/services) that the service you need has client and interfaces defined. If it does, you can skip to [2. Add a Code Generation Recipe](#2-add-a-code-generation-recipe).
26+
2. If the service does not exist, add an instance of service you want to add to [`codegen/services/clients.go`](codegen/services/clients.go).
27+
3. Add the relevant Datadog SDK import to the top of the file.
28+
4. [Run Code Generation](#run-code-generation) to generate the service interfaces.
29+
5. Ensure the new service has a `//go:generate mockgen` (see examples from above) and run `make generate` to generate the mocks.
30+
31+
## 2. Add a Code Generation Recipe
32+
33+
Every supported Datadog service has a recipe file under [`codegen/recipes`](codegen/recipes). For example, all Users resources are listed in [`codegen/recipes/users.go`](codegen/recipes/users.go).
34+
35+
In the following example, we will use the fictional `MyService` Datadog service with `MyResource` resource as an example. We recommend taking a look at a few examples in [codegen/recipes](codegen/recipes) first, as these steps will make more sense with some examples to reference.
36+
37+
If you are adding a service that needs a new recipe, see [Add a New Recipe File](#add-a-new-recipe-file). Otherwise, if the Datadog service is already supported but is missing resource(s), you may skip to [Add a Resource to a Recipe](#add-a-resource-to-a-recipe).
38+
39+
### Add a New Recipe File
40+
41+
The process to follow for adding a new recipe is:
42+
43+
1. Add a new file under [`codegen/recipes`](codegen/recipes) called `myservice.go` under a package named `recipes`.
44+
2. Inside the new file, add a function called `MyServiceResources()` that returns `[]Resource`.
45+
3. Add my service to all resources by adding `recipes.MyServiceResources,` to [`codegen/main.go`](codegen/main.go#L17)
46+
4. Define the list of resources to be generated. See [Add a Resource to a Recipe](#add-a-resource-to-a-recipe) for more details.
47+
48+
### Add a Resource to a Recipe
49+
50+
`MyServiceResources()` should return an array of `Resource` instances. Like on example below
51+
52+
```go
53+
func MyServiceResources() []*Resource {
54+
resources := []*Resource{
55+
{
56+
SubService: "my_service",
57+
Multiplex: "client.AccountMultiplex",
58+
Struct: new(datadogV2.User),
59+
SkipFields: []string{"Id"},
60+
ExtraColumns: append(defaultAccountColumns, codegen.ColumnDefinition{
61+
Name: "id",
62+
Type: schema.TypeString,
63+
Resolver: `schema.PathResolver("Id")`,
64+
Options: schema.ColumnCreationOptions{PrimaryKey: true},
65+
}),
66+
Relations: []string{"MyServiceAttachments()", "MyServicePermissions()"},
67+
},
68+
{
69+
SubService: "my_service_attachments",
70+
Struct: new(datadogV2.Permission),
71+
ExtraColumns: defaultAccountColumns,
72+
},
73+
{
74+
SubService: "my_service_permissions",
75+
Struct: new(datadogV2.User),
76+
ExtraColumns: defaultAccountColumns,
77+
},
78+
}
79+
80+
// set default values
81+
for _, r := range resources {
82+
r.Service = "my_service"
83+
}
84+
return resources
85+
}
86+
```
87+
88+
### Run Code Generation
89+
90+
With the recipe file added and some resources defined, you are ready to run code generation. Run:
91+
92+
```shell
93+
make gen-code
94+
```
95+
96+
This will update all resources and generate a new directory for your service under [resources/services](resources/services).
97+
It should create the table files for your resources.
98+
For each table fetch and mock test files should be added. for example for `my_service.go` the `my_service_fetch.go` and `my_service_mock_test.go` files should be created
99+
100+
## General Tips
101+
102+
- Keep transformations to a minimum. As far as possible, we aim to deliver an accurate reflection of what the Datadog API provides.
103+
- We generally only unroll structs one level deep. Nested structs should be transformed into JSON columns.
104+
- It's recommended to split each resource addition into a separate PR. This makes it easier to review and merge.
105+
- Before submitting a pull request, run `make gen-docs` to generate documentation for the table. Include these generated files in the pull request.
106+
- If you get stuck or need help, feel free to reach out on [Discord](https://www.cloudquery.io/discord). We are a friendly community and would love to help!

plugins/source/datadog/Makefile

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Generate mocks for mock/unit testing
2+
.PHONY: generate-mocks
3+
generate-mocks:
4+
go generate ./client/services/...
5+
6+
# Test unit
7+
.PHONY: test
8+
test:
9+
go test -timeout 3m ./...
10+
11+
# Install tools
12+
.PHONY: install-tools
13+
install-tools:
14+
@echo Installing tools from tools/tool.go
15+
@cat tools/tool.go | grep _ | awk -F'"' '{print $$2}' | xargs -tI % go install %
16+
17+
# Install pre-commit hooks. This requires pre-commit to be installed (https://pre-commit.com/)
18+
.PHONY: install-hooks
19+
install-hooks:
20+
pre-commit install
21+
22+
.PHONY: gen-docs
23+
gen-docs:
24+
rm -rf ./docs/tables/*
25+
go run main.go doc ./docs/tables
26+
27+
.PHONY: lint
28+
lint:
29+
golangci-lint run --config ../../.golangci.yml
30+
31+
.PHONY: gen-code
32+
gen-code:
33+
go run codegen/main.go
34+
35+
# All gen targets
36+
.PHONY: gen
37+
gen: gen-code gen-docs

0 commit comments

Comments
 (0)