Skip to content

Commit 88c74e5

Browse files
Add automated OpenAPI specification for mgmt_api (drasi-project#309)
Add automated OpenAPI specification for mgmt_api This commit introduces a robust, automated system for generating and maintaining an OpenAPI 3.0 specification for the management API. This provides a version-controlled API contract that is always in sync with the implementation. The previous macro-based routes have been refactored into explicit Actix handlers. Generic DTOs in the API layer were replaced with concrete structs (e.g., SourceDto) to resolve a utoipa limitation and produce a valid spec. Key changes include: - Integrated the utoipa crate to generate the spec from Rust code. - Aligns the mgmt_api crate version to 1.0.0 to match the /v1 API path. - Adds a pre-commit hook to enforce local spec updates. - Adds CI jobs to verify spec sync and detect breaking changes. - verify-openapi-spec: Fails the build if the committed spec is out of date. - detect-breaking-api-changes: Uses openapi-diff to prevent merging backward-incompatible changes. Signed-off-by: Aman Singh <aman.singh.original@gmail.com>
1 parent 0c7c99a commit 88c74e5

46 files changed

Lines changed: 3832 additions & 579 deletions

Some content is hidden

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

.githooks/pre-commit

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,22 @@ case ":${PATH}:" in
77
;;
88
esac
99

10+
echo "Running pre-commit hook: Checking for API spec changes..."
11+
12+
# Generate the latest spec based on the current code
13+
make -C control-planes/mgmt_api openapi-generate
14+
15+
# Check if the generated spec file has unstaged changes
16+
if ! git diff --quiet HEAD control-planes/mgmt_api/openapi.yaml; then
17+
echo "\nERROR: API specification is out of date."
18+
echo "The OpenAPI spec has been regenerated based on your code changes."
19+
echo "Please stage the updated file to include it in your commit:"
20+
echo "\n git add control-planes/mgmt_api/openapi.yaml\n"
21+
exit 1
22+
fi
23+
24+
echo "API spec is up to date."
25+
1026
echo "Running cargo fmt for query container..."
1127
cargo fmt --manifest-path ./query-container/Cargo.toml --check
1228

.github/workflows/build-test.yml

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,87 @@ permissions:
3333
packages: write
3434

3535
jobs:
36+
verify-openapi-spec:
37+
name: Verify OpenAPI Specification
38+
runs-on: ubuntu-latest
39+
steps:
40+
- name: Checkout repository
41+
uses: actions/checkout@v4
42+
43+
- name: Install system dependencies
44+
run: |
45+
sudo apt-get update
46+
sudo apt-get install -y protobuf-compiler
47+
48+
- name: Install Rust toolchain
49+
uses: actions-rs/toolchain@v1
50+
with:
51+
toolchain: stable
52+
override: true
53+
54+
- name: Cache Cargo dependencies
55+
uses: actions/cache@v4
56+
with:
57+
path: |
58+
~/.cargo/registry
59+
~/.cargo/git
60+
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
61+
62+
- name: Generate OpenAPI Spec
63+
run: make -C control-planes/mgmt_api openapi-generate
64+
65+
- name: Check for diff
66+
run: |
67+
if ! git diff --quiet HEAD control-planes/mgmt_api/openapi.yaml; then
68+
echo "ERROR: The generated OpenAPI specification is out of date."
69+
echo "Please run 'make -C control-planes/mgmt_api openapi-generate' and commit the changes."
70+
exit 1
71+
fi
72+
echo "OpenAPI specification is up to date."
73+
74+
detect-breaking-api-changes:
75+
name: Detect Breaking API Changes
76+
runs-on: ubuntu-latest
77+
# TODO: Enable this job after the initial OpenAPI PR is merged
78+
# For now, skip it since there's no spec in main branch to compare against
79+
if: false
80+
# if: github.base_ref == 'main' && github.event_name == 'pull_request'
81+
steps:
82+
- name: Checkout PR branch
83+
uses: actions/checkout@v4
84+
85+
- name: Checkout base branch (main)
86+
uses: actions/checkout@v4
87+
with:
88+
ref: main
89+
path: main
90+
91+
- name: Install system dependencies
92+
run: |
93+
sudo apt-get update
94+
sudo apt-get install -y protobuf-compiler
95+
96+
- name: Install Rust toolchain
97+
uses: actions-rs/toolchain@v1
98+
with:
99+
toolchain: stable
100+
override: true
101+
102+
- name: Generate OpenAPI Spec for PR
103+
run: make -C control-planes/mgmt_api openapi-generate
104+
105+
- name: Generate OpenAPI Spec for main branch
106+
run: |
107+
cd main
108+
make -C control-planes/mgmt_api openapi-generate
109+
110+
- name: Install openapi-diff
111+
run: npm install -g openapi-diff
112+
113+
- name: Run openapi-diff
114+
run: |
115+
openapi-diff main/control-planes/mgmt_api/openapi.yaml control-planes/mgmt_api/openapi.yaml --fail-on-incompatible
116+
36117
build-images:
37118
permissions:
38119
packages: write

control-planes/mgmt_api/.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
1-
/target
1+
/target
2+
openapitools.json
3+
# Allow src/bin for Rust binary sources
4+
!/src/bin/

control-planes/mgmt_api/Cargo.lock

Lines changed: 160 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

control-planes/mgmt_api/Cargo.toml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,21 @@
11
[package]
22
name = "mgmt_api"
3-
version = "0.1.0"
3+
version = "1.0.0"
44
edition = "2021"
55

6+
[[bin]]
7+
name = "generate-spec"
8+
path = "src/bin/generate-spec.rs"
9+
610
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
711

812
[dependencies]
913
resource_provider_api = { path = "../resource_provider_api" }
1014
drasi-comms-abstractions = { path = "../../infrastructure/comms-abstractions" }
1115
drasi-comms-dapr = { path = "../../infrastructure/comms-dapr" }
1216
dapr = "=0.15.1"
17+
utoipa = { version = "4", features = ["actix_extras", "chrono", "yaml"] }
18+
utoipa-swagger-ui = { version = "6", features = ["actix-web"] }
1319
async-stream = "0.3.5"
1420
async-trait = "0.1"
1521
actix = "0.13"

control-planes/mgmt_api/Dockerfile.azure-linux

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ WORKDIR /usr/src/control-planes/mgmt_api
2424
COPY ./control-planes/mgmt_api/Cargo.toml .
2525
RUN cargo fetch
2626
COPY ./control-planes/mgmt_api .
27-
RUN cargo install --force --path .
27+
RUN cargo install --force --path . --bin mgmt_api
2828

2929
FROM mcr.microsoft.com/azurelinux/distroless/base:3.0
3030
COPY --from=builder /usr/local/cargo/bin/mgmt_api /usr/local/bin/mgmt_api

0 commit comments

Comments
 (0)