Skip to content

Commit 8d011f3

Browse files
authored
Focus v0.1 on Datadog migration plans (#1)
Make deterministic, read-only Datadog to Grafana LGTM migration planning the primary v0.1 product surface.
1 parent 2848805 commit 8d011f3

34 files changed

Lines changed: 5482 additions & 576 deletions

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,6 @@ demo/
33
*.zip
44
coverage.out
55
dist/
6+
examples/datadog-to-grafana/.openexit/
7+
examples/datadog-to-grafana/migration/
68
.DS_Store

CHANGELOG.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,14 @@
22

33
## Unreleased
44

5+
## 0.1.0 - 2026-07-18
6+
7+
- Refocused the v0.1 product on one workflow: `openexit datadog scan`, `plan --target grafana-lgtm`, and `export --out <directory>`.
8+
- Added a versioned, endpoint-auditable Datadog observability catalog with GET-only collection, full pagination, redacted evidence, fail-closed partial-scan handling, and stale-plan invalidation.
9+
- Added deterministic per-resource and per-component conversion statuses (`exact`, `approximate`, `manual`, and `unsupported`) with explicit semantic changes and no fake `vector(0)` alert placeholders.
10+
- Added source-linked Grafana dashboards, Prometheus alert candidates, Alloy/OpenTelemetry baselines, a self-contained HTML migration report, and a transparent exit-readiness formula.
11+
- Added schema-backed provenance and validation manifests plus transactional directory export with per-file source references and `SHA256SUMS`.
12+
- Moved the earlier multi-provider engine under `openexit experimental` while retaining hidden root aliases for compatibility.
513
- Added `openexit doctor` for local runtime diagnostics covering version metadata, embedded schemas, and optional validator availability.
614
- Added preview support for fixture-based OpenAI/Anthropic to vLLM/LiteLLM assessment.
715
- Added explicit source/target project initialization and validation consistency checks for all assessment paths.
@@ -47,8 +55,6 @@
4755
- Updated push CI to run the same release readiness gate, including smoke pipelines and bundle verification.
4856
- Updated CI and release workflows to Node.js 24-native GitHub Actions.
4957

50-
## 0.1.0 - 2026-05-24
51-
5258
- Initial OpenExit implementation.
5359
- Added mocked live Datadog collector coverage and evidence ref hardening.
5460
- Added conservative simple Datadog threshold to PromQL candidate conversion.

CONTRIBUTING.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,15 @@ make build
1111
make release-dist VERSION=0.1.0-dev
1212
```
1313

14-
Keep changes local-first and deterministic. New collectors must default to read-only behavior, must never store credentials, and must redact raw evidence before it is written to disk.
14+
Keep changes local-first and deterministic. The primary Datadog client must remain GET-only, must never store credentials, and must redact source evidence before it is written to disk.
1515

1616
## Design Principles
1717

1818
- Prefer explicit risk and manual-review flags over optimistic conversion.
19-
- Keep AI optional and outside the source of truth.
20-
- Add tests for new analyzer rules, collectors, and generated artifacts.
19+
- Keep AI conversion and automatic deployment out of the primary v0.1 workflow.
20+
- Add tests for catalog endpoints, pagination, redaction, converters, provenance, scoring, and generated artifacts.
2121
- Generated target files must be labeled as candidates.
22+
- Never emit executable placeholders for behavior that was not translated.
2223

2324
## Pull Requests
2425

Makefile

Lines changed: 60 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ RELEASE_ASSETS ?= install.sh openexit.bash _openexit openexit.fish openexit.ps1
1212
GOLANGCI_LINT_VERSION ?= v2.12.2
1313
GOLANGCI_LINT ?= bin/golangci-lint
1414
EXAMPLE_INPUT ?= examples/datadog-to-grafana/input/datadog-fixture.json
15-
EXAMPLE_DIR ?= examples/datadog-to-grafana/output
16-
EXAMPLE_BUNDLE ?= examples/datadog-to-grafana/openexit-example.zip
15+
EXAMPLE_STATE ?= examples/datadog-to-grafana/.openexit
16+
EXAMPLE_DIR ?= examples/datadog-to-grafana/migration
1717

18-
.PHONY: build test fmt fmt-check lint golangci-lint smoke example example-smoke verify release-dist install-smoke release-check clean
18+
.PHONY: build test fmt fmt-check lint golangci-lint smoke experimental-smoke example example-smoke verify release-dist install-smoke release-check clean
1919

2020
build:
2121
mkdir -p $(dir $(BINARY))
@@ -41,82 +41,76 @@ smoke:
4141
tmp=$$(mktemp -d); \
4242
trap 'rm -rf "$$tmp"' EXIT; \
4343
$(BINARY) doctor; \
44-
$(BINARY) demo "$$tmp/builtin-demo" --out "$$tmp/builtin-demo.zip"; \
44+
$(BINARY) datadog scan --fixture ./testdata/datadog/small.json --workdir "$$tmp/.openexit"; \
45+
$(BINARY) datadog plan --target grafana-lgtm --workdir "$$tmp/.openexit"; \
46+
$(BINARY) datadog export --out "$$tmp/migration" --workdir "$$tmp/.openexit"; \
47+
test -s "$$tmp/migration/index.html"; \
48+
test -s "$$tmp/migration/manifest.json"; \
49+
test -s "$$tmp/migration/SHA256SUMS"; \
50+
! grep -R 'vector(0)' "$$tmp/migration/generated"
51+
52+
experimental-smoke:
53+
tmp=$$(mktemp -d); \
54+
trap 'rm -rf "$$tmp"' EXIT; \
55+
$(BINARY) experimental demo "$$tmp/builtin-demo" --out "$$tmp/builtin-demo.zip"; \
4556
test -s "$$tmp/builtin-demo.zip"; \
4657
$(BINARY) verify-bundle "$$tmp/builtin-demo.zip"; \
47-
$(BINARY) init "$$tmp/datadog-demo"; \
48-
$(BINARY) collect fixture --project "$$tmp/datadog-demo" --input ./testdata/datadog/small.json; \
49-
$(BINARY) assess --project "$$tmp/datadog-demo" --target grafana-lgtm; \
50-
$(BINARY) map --project "$$tmp/datadog-demo"; \
51-
$(BINARY) generate --project "$$tmp/datadog-demo" --all; \
52-
$(BINARY) validate --project "$$tmp/datadog-demo"; \
53-
$(BINARY) export --project "$$tmp/datadog-demo" --format zip --out "$$tmp/openexit-demo.zip"; \
58+
$(BINARY) experimental init "$$tmp/datadog-demo"; \
59+
$(BINARY) experimental collect fixture --project "$$tmp/datadog-demo" --input ./testdata/datadog/small.json; \
60+
$(BINARY) experimental assess --project "$$tmp/datadog-demo" --target grafana-lgtm; \
61+
$(BINARY) experimental map --project "$$tmp/datadog-demo"; \
62+
$(BINARY) experimental generate --project "$$tmp/datadog-demo" --all; \
63+
$(BINARY) experimental validate --project "$$tmp/datadog-demo"; \
64+
$(BINARY) experimental export --project "$$tmp/datadog-demo" --format zip --out "$$tmp/openexit-demo.zip"; \
5465
$(BINARY) verify-bundle "$$tmp/openexit-demo.zip"; \
55-
$(BINARY) init "$$tmp/ghe-demo" --source github-enterprise --target forgejo; \
56-
$(BINARY) collect github-fixture --project "$$tmp/ghe-demo" --input ./testdata/github-enterprise/small.json; \
57-
$(BINARY) assess --project "$$tmp/ghe-demo" --target forgejo; \
58-
$(BINARY) map --project "$$tmp/ghe-demo"; \
59-
$(BINARY) generate --project "$$tmp/ghe-demo" --all; \
60-
$(BINARY) validate --project "$$tmp/ghe-demo"; \
61-
$(BINARY) export --project "$$tmp/ghe-demo" --format zip --out "$$tmp/ghe-demo.zip"; \
66+
$(BINARY) experimental init "$$tmp/ghe-demo" --source github-enterprise --target forgejo; \
67+
$(BINARY) experimental collect github-fixture --project "$$tmp/ghe-demo" --input ./testdata/github-enterprise/small.json; \
68+
$(BINARY) experimental assess --project "$$tmp/ghe-demo" --target forgejo; \
69+
$(BINARY) experimental map --project "$$tmp/ghe-demo"; \
70+
$(BINARY) experimental generate --project "$$tmp/ghe-demo" --all; \
71+
$(BINARY) experimental validate --project "$$tmp/ghe-demo"; \
72+
$(BINARY) experimental export --project "$$tmp/ghe-demo" --format zip --out "$$tmp/ghe-demo.zip"; \
6273
$(BINARY) verify-bundle "$$tmp/ghe-demo.zip"; \
63-
$(BINARY) init "$$tmp/identity-demo" --source identity --target keycloak-zitadel; \
64-
$(BINARY) collect identity-fixture --project "$$tmp/identity-demo" --input ./testdata/identity/small.json; \
65-
$(BINARY) assess --project "$$tmp/identity-demo" --target keycloak-zitadel; \
66-
$(BINARY) map --project "$$tmp/identity-demo"; \
67-
$(BINARY) generate --project "$$tmp/identity-demo" --all; \
68-
$(BINARY) validate --project "$$tmp/identity-demo"; \
69-
$(BINARY) export --project "$$tmp/identity-demo" --format zip --out "$$tmp/identity-demo.zip"; \
74+
$(BINARY) experimental init "$$tmp/identity-demo" --source identity --target keycloak-zitadel; \
75+
$(BINARY) experimental collect identity-fixture --project "$$tmp/identity-demo" --input ./testdata/identity/small.json; \
76+
$(BINARY) experimental assess --project "$$tmp/identity-demo" --target keycloak-zitadel; \
77+
$(BINARY) experimental map --project "$$tmp/identity-demo"; \
78+
$(BINARY) experimental generate --project "$$tmp/identity-demo" --all; \
79+
$(BINARY) experimental validate --project "$$tmp/identity-demo"; \
80+
$(BINARY) experimental export --project "$$tmp/identity-demo" --format zip --out "$$tmp/identity-demo.zip"; \
7081
$(BINARY) verify-bundle "$$tmp/identity-demo.zip"; \
71-
$(BINARY) init "$$tmp/edge-demo" --source edge --target varnish-haproxy-coraza; \
72-
$(BINARY) collect edge-fixture --project "$$tmp/edge-demo" --input ./testdata/edge/small.json; \
73-
$(BINARY) assess --project "$$tmp/edge-demo" --target varnish-haproxy-coraza; \
74-
$(BINARY) map --project "$$tmp/edge-demo"; \
75-
$(BINARY) generate --project "$$tmp/edge-demo" --all; \
76-
$(BINARY) validate --project "$$tmp/edge-demo"; \
77-
$(BINARY) export --project "$$tmp/edge-demo" --format zip --out "$$tmp/edge-demo.zip"; \
82+
$(BINARY) experimental init "$$tmp/edge-demo" --source edge --target varnish-haproxy-coraza; \
83+
$(BINARY) experimental collect edge-fixture --project "$$tmp/edge-demo" --input ./testdata/edge/small.json; \
84+
$(BINARY) experimental assess --project "$$tmp/edge-demo" --target varnish-haproxy-coraza; \
85+
$(BINARY) experimental map --project "$$tmp/edge-demo"; \
86+
$(BINARY) experimental generate --project "$$tmp/edge-demo" --all; \
87+
$(BINARY) experimental validate --project "$$tmp/edge-demo"; \
88+
$(BINARY) experimental export --project "$$tmp/edge-demo" --format zip --out "$$tmp/edge-demo.zip"; \
7889
$(BINARY) verify-bundle "$$tmp/edge-demo.zip"; \
79-
$(BINARY) init "$$tmp/ai-demo" --source ai-provider --target vllm-litellm; \
80-
$(BINARY) collect ai-fixture --project "$$tmp/ai-demo" --input ./testdata/ai-provider/small.json; \
81-
$(BINARY) assess --project "$$tmp/ai-demo" --target vllm-litellm; \
82-
$(BINARY) map --project "$$tmp/ai-demo"; \
83-
$(BINARY) generate --project "$$tmp/ai-demo" --all; \
84-
$(BINARY) validate --project "$$tmp/ai-demo"; \
85-
$(BINARY) export --project "$$tmp/ai-demo" --format zip --out "$$tmp/ai-demo.zip"; \
90+
$(BINARY) experimental init "$$tmp/ai-demo" --source ai-provider --target vllm-litellm; \
91+
$(BINARY) experimental collect ai-fixture --project "$$tmp/ai-demo" --input ./testdata/ai-provider/small.json; \
92+
$(BINARY) experimental assess --project "$$tmp/ai-demo" --target vllm-litellm; \
93+
$(BINARY) experimental map --project "$$tmp/ai-demo"; \
94+
$(BINARY) experimental generate --project "$$tmp/ai-demo" --all; \
95+
$(BINARY) experimental validate --project "$$tmp/ai-demo"; \
96+
$(BINARY) experimental export --project "$$tmp/ai-demo" --format zip --out "$$tmp/ai-demo.zip"; \
8697
$(BINARY) verify-bundle "$$tmp/ai-demo.zip"
8798

8899
example: build
89-
rm -rf $(EXAMPLE_DIR)/openexit.yaml \
90-
$(EXAMPLE_DIR)/inventory \
91-
$(EXAMPLE_DIR)/assessment \
92-
$(EXAMPLE_DIR)/mapping \
93-
$(EXAMPLE_DIR)/generated-config \
94-
$(EXAMPLE_DIR)/evidence \
95-
$(EXAMPLE_DIR)/validation \
96-
$(EXAMPLE_BUNDLE)
97-
mkdir -p $(EXAMPLE_DIR)
98-
$(BINARY) init $(EXAMPLE_DIR) --source datadog --target grafana-lgtm
99-
$(BINARY) collect fixture --project $(EXAMPLE_DIR) --input $(EXAMPLE_INPUT)
100-
$(BINARY) assess --project $(EXAMPLE_DIR) --target grafana-lgtm
101-
$(BINARY) map --project $(EXAMPLE_DIR)
102-
$(BINARY) generate --project $(EXAMPLE_DIR) --all
103-
$(BINARY) validate --project $(EXAMPLE_DIR)
104-
$(BINARY) export --project $(EXAMPLE_DIR) --format zip --out $(EXAMPLE_BUNDLE)
100+
$(BINARY) datadog scan --fixture $(EXAMPLE_INPUT) --workdir $(EXAMPLE_STATE)
101+
$(BINARY) datadog plan --target grafana-lgtm --workdir $(EXAMPLE_STATE)
102+
$(BINARY) datadog export --force --out $(EXAMPLE_DIR) --workdir $(EXAMPLE_STATE)
105103

106104
example-smoke: build
107105
tmp=$$(mktemp -d); \
108106
trap 'rm -rf "$$tmp"' EXIT; \
109-
$(BINARY) init "$$tmp/example" --source datadog --target grafana-lgtm; \
110-
$(BINARY) collect fixture --project "$$tmp/example" --input ./$(EXAMPLE_INPUT); \
111-
$(BINARY) assess --project "$$tmp/example" --target grafana-lgtm; \
112-
$(BINARY) map --project "$$tmp/example"; \
113-
$(BINARY) generate --project "$$tmp/example" --all; \
114-
$(BINARY) validate --project "$$tmp/example"; \
115-
$(BINARY) export --project "$$tmp/example" --format zip --out "$$tmp/openexit-example.zip"; \
116-
$(BINARY) verify-bundle "$$tmp/openexit-example.zip"; \
117-
test -s "$$tmp/openexit-example.zip"
118-
119-
verify: lint test build smoke example-smoke
107+
$(BINARY) datadog scan --fixture ./$(EXAMPLE_INPUT) --workdir "$$tmp/.openexit"; \
108+
$(BINARY) datadog plan --target grafana-lgtm --workdir "$$tmp/.openexit"; \
109+
$(BINARY) datadog export --out "$$tmp/migration" --workdir "$$tmp/.openexit"; \
110+
test -s "$$tmp/migration/index.html"; \
111+
test -s "$$tmp/migration/manifest.json"
112+
113+
verify: lint test build smoke experimental-smoke example-smoke
120114

121115
release-dist:
122116
rm -rf dist

0 commit comments

Comments
 (0)