Skip to content

Commit e789d6e

Browse files
committed
Merge branch 'main' into feat/k8s-deploy
Signed-off-by: S3B4SZ17 <[email protected]>
2 parents 2839780 + ae08b12 commit e789d6e

File tree

13 files changed

+155
-102
lines changed

13 files changed

+155
-102
lines changed

.dockerignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,3 @@ README.md
1414
__pycache__/*
1515
lib/
1616
.python-version
17-
*.yaml

.github/workflows/publish.yaml

Lines changed: 15 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,7 @@ on:
77
paths:
88
- pyproject.toml
99
workflow_dispatch:
10-
inputs:
11-
version:
12-
description: 'Version to publish'
13-
required: false
14-
default: 'latest'
15-
type: string
10+
1611

1712
jobs:
1813
push_to_registry:
@@ -21,40 +16,11 @@ jobs:
2116
permissions:
2217
contents: read # required for actions/checkout
2318
packages: write # required for pushing to ghcr.io
19+
id-token: write # required for signing with cosign
2420
steps:
2521
- name: Check out the repo
2622
uses: actions/checkout@v4
2723

28-
- name: Setup python
29-
uses: actions/setup-python@v5
30-
with:
31-
python-version: '3.10'
32-
cache: 'poetry'
33-
34-
- name: Install dependencies
35-
run: poetry install
36-
37-
- name: Install uv
38-
uses: astral-sh/setup-uv@v5
39-
with:
40-
version: "0.7.17"
41-
42-
- name: Download dependencies
43-
run: |
44-
uv sync
45-
46-
- name: Run ruff
47-
run: |
48-
uvx ruff check --fix --config ruff.toml
49-
50-
- name: Run Unit Tests
51-
run: |
52-
uv run pytest --capture=tee-sys --junitxml=pytest.xml
53-
54-
- name: Run Test Coverage
55-
run: |
56-
uv run pytest --cov=. --cov-report=xml
57-
5824
- name: Extract version
5925
id: extract_version
6026
run: |
@@ -68,7 +34,13 @@ jobs:
6834
username: ${{ github.actor }}
6935
password: ${{ secrets.GITHUB_TOKEN }}
7036

37+
- name: Install cosign
38+
uses: sigstore/cosign-installer@59acb6260d9c0ba8f4a2f9d9b48431a222b68e20 # v3.5.0
39+
with:
40+
cosign-release: 'v2.2.4'
41+
7142
- name: Build and push Docker image
43+
id: build-and-push
7244
uses: docker/build-push-action@v5
7345
with:
7446
context: .
@@ -77,40 +49,10 @@ jobs:
7749
ghcr.io/sysdiglabs/sysdig-mcp-server:latest
7850
ghcr.io/sysdiglabs/sysdig-mcp-server:v${{ steps.extract_version.outputs.VERSION }}
7951
80-
- name: "Check test reports exists"
81-
if: always()
82-
id: check-test-results-exists
83-
uses: andstor/file-existence-action@v3
84-
with:
85-
files: "pytest.xml, coverage.xml"
86-
87-
- name: Create pack-wise pytest report
88-
run: poetry run python .github/github_workflow_scripts/parse_junit_per_pack.py
89-
if: |
90-
always() &&
91-
steps.check-test-results-exists.outputs.files_exists == 'true' &&
92-
github.event.pull_request.head.repo.fork == false
93-
94-
- name: Upload junit & pack-wise pytest report
95-
uses: PaloAltoNetworks/[email protected]
96-
if: |
97-
always() &&
98-
steps.check-test-results-exists.outputs.files_exists == 'true' &&
99-
github.event.pull_request.head.repo.fork == false
100-
with:
101-
name: pytest
102-
path: |
103-
coverage.xml
104-
if-no-files-found: error
105-
106-
- name: Pytest coverage comment
107-
if: |
108-
always() &&
109-
steps.check-test-results-exists.outputs.files_exists == 'true' &&
110-
steps.check-test-results-exists.outputs.files_exists == 'true' &&
111-
! github.event.pull_request.head.repo.fork
112-
uses: MishaKav/[email protected]
113-
continue-on-error: true # may fail on output > 65k chars
114-
with:
115-
pytest-xml-coverage-path: coverage.xml
116-
junitxml-path: coverage.xml
52+
- name: Sign the published Docker image
53+
env:
54+
TAGS: |
55+
ghcr.io/sysdiglabs/sysdig-mcp-server:latest
56+
ghcr.io/sysdiglabs/sysdig-mcp-server:v${{ steps.extract_version.outputs.VERSION }}
57+
DIGEST: ${{ steps.build-and-push.outputs.digest }}
58+
run: echo "${TAGS}" | xargs -I {} cosign sign --yes {}@${DIGEST}

.github/workflows/test.yaml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
name: Test
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
9+
jobs:
10+
test:
11+
name: Test
12+
runs-on: ubuntu-latest
13+
permissions:
14+
contents: read # required for actions/checkout
15+
steps:
16+
- name: Check out the repo
17+
uses: actions/checkout@v4
18+
19+
- name: Setup python
20+
uses: actions/setup-python@v5
21+
with:
22+
python-version: "3.10"
23+
24+
- name: Install uv
25+
uses: astral-sh/setup-uv@v5
26+
with:
27+
version: "0.7.17"
28+
29+
- name: Download dependencies
30+
run: make init
31+
32+
- name: Run ruff
33+
run: make lint
34+
35+
- name: Run Unit Tests
36+
run: make test

.pre-commit-config.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@ repos:
44
- id: ruff-format
55
name: Ruff Format
66
description: Format code with ruff.
7-
entry: bash -c 'uvx ruff format --config ruff.toml'
7+
entry: make fmt
88
language: system
99
stages: ["commit", "push"]
1010
- id: ruff-check
1111
name: Ruff Check
1212
description: Check code style with ruff.
13-
entry: bash -c 'uvx ruff check --config ruff.toml'
13+
entry: make lint
1414
language: system
1515
stages: ["commit", "push"]

CODEOWNERS

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# These owners will be the default owners for everything in
2-
# the repo. Unless a later match takes precedence,
2+
3+
# the repo. Unless a later match takes precedence
4+
35
# @S3B4SZ17 @alecron and @sysdiglabs/sysdig-training will be requested for
4-
# review when someone opens a pull request.
5-
* @S3B4SZ17 @alecron @sysdiglabs/sysdig-training
6+
7+
# review when someone opens a pull request
8+
9+
* @sysdiglabs/sysdig-training

Dockerfile

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,24 +8,29 @@ ENV UV_COMPILE_BYTECODE=1 UV_LINK_MODE=copy
88

99
WORKDIR /app
1010
COPY . /app
11+
RUN apt update && apt install -y git
1112
RUN --mount=type=cache,target=/root/.cache/uv \
12-
--mount=type=bind,source=uv.lock,target=uv.lock \
13-
--mount=type=bind,source=pyproject.toml,target=pyproject.toml \
14-
uv sync --locked --no-install-project --no-editable --no-dev
13+
--mount=type=bind,source=uv.lock,target=uv.lock \
14+
--mount=type=bind,source=pyproject.toml,target=pyproject.toml \
15+
uv sync --locked --no-install-project --no-editable --no-dev
1516
RUN --mount=type=cache,target=/root/.cache/uv \
1617
uv sync --locked --no-editable --no-dev
1718

18-
# Dinal image without uv
19+
RUN uv build
20+
RUN mv ./dist/sysdig_mcp_server-*.tar.gz /tmp/sysdig_mcp_server.tar.gz
21+
22+
# Final image without uv
1923
FROM python:3.12-slim
2024
# It is important to use the image that matches the builder, as the path to the
2125
# Python executable must be the same
2226

23-
# Copy the application from the builder
24-
COPY --from=builder --chown=app:app /app /app
25-
2627
WORKDIR /app
2728

28-
# Place executables in the environment at the front of the path
29-
ENV PATH="/app/.venv/bin:$PATH"
29+
RUN apt update && apt install -y git
30+
# Copy the application from the builder
31+
COPY --from=builder --chown=app:app /tmp/sysdig_mcp_server.tar.gz /app
32+
COPY --from=builder --chown=app:app /app/app_config.yaml /app
33+
34+
RUN pip install /app/sysdig_mcp_server.tar.gz
3035

31-
ENTRYPOINT ["/bin/sh", "entrypoint.sh"]
36+
ENTRYPOINT ["sysdig-mcp-server"]

LICENSE.txt

Lines changed: 0 additions & 1 deletion
This file was deleted.

Makefile

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
.PHONY: help init lint fmt test test-coverage
2+
3+
help:
4+
@echo "Available commands:"
5+
@echo " make init - Install dependencies"
6+
@echo " make lint - Lint and fix code"
7+
@echo " make fmt - Format code"
8+
@echo " make test - Run tests"
9+
@echo " make test-coverage - Run tests and generate coverage report"
10+
11+
init:
12+
uv sync
13+
14+
lint:
15+
uvx ruff check --fix --config ruff.toml
16+
17+
fmt:
18+
uvx ruff format --config ruff.toml
19+
20+
test:
21+
uv run pytest --capture=tee-sys --junitxml=pytest.xml
22+
23+
test-coverage:
24+
uv run pytest --cov=. --cov-report=xml

README.md

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ This file contains the main configuration for the application, including:
111111
The following environment variables are required for configuring the Sysdig SDK:
112112

113113
- `SYSDIG_HOST`: The URL of your Sysdig Secure instance (e.g., `https://secure.sysdig.com`).
114-
- `SYSDIG_SECURE_API_TOKEN`: Your Sysdig Secure API token.
114+
- `SYSDIG_SECURE_TOKEN`: Your Sysdig Secure API token.
115115

116116
You can find your API token in the Sysdig Secure UI under **Settings > Sysdig Secure API**. Make sure to copy the token as it will not be shown again.
117117

@@ -139,13 +139,13 @@ docker build -t sysdig-mcp-server .
139139
Then, you can run the container, making sure to pass the required environment variables:
140140

141141
```bash
142-
docker run -e SYSDIG_HOST=<your_sysdig_host> -e SYSDIG_SECURE_API_TOKEN=<your_sysdig_secure_api_token> -p 8080:8080 sysdig-mcp-server
142+
docker run -e SYSDIG_HOST=<your_sysdig_host> -e SYSDIG_SECURE_TOKEN=<your_sysdig_secure_api_token> -p 8080:8080 sysdig-mcp-server
143143
```
144144

145145
By default, the server will run using the `stdio` transport. To use the `streamable-http` or `sse` transports, set the `MCP_TRANSPORT` environment variable to `streamable-http` or `sse`:
146146

147147
```bash
148-
docker run -e MCP_TRANSPORT=streamable-http -e SYSDIG_HOST=<your_sysdig_host> -e SYSDIG_SECURE_API_TOKEN=<your_sysdig_secure_api_token> -p 8080:8080 sysdig-mcp-server
148+
docker run -e MCP_TRANSPORT=streamable-http -e SYSDIG_HOST=<your_sysdig_host> -e SYSDIG_SECURE_TOKEN=<your_sysdig_secure_api_token> -p 8080:8080 sysdig-mcp-server
149149
```
150150

151151
### K8s Deployment
@@ -254,7 +254,36 @@ For the Claude Desktop app, you can manually configure the MCP server by editing
254254
],
255255
"env": {
256256
"SYSDIG_HOST": "<your_sysdig_host>",
257-
"SYSDIG_SECURE_API_TOKEN": "<your_sysdig_secure_api_token>",
257+
"SYSDIG_SECURE_TOKEN": "<your_sysdig_secure_api_token>",
258+
"MCP_TRANSPORT": "stdio"
259+
}
260+
}
261+
}
262+
}
263+
```
264+
265+
Or, alternatively, if you want to use docker, you can add the following configuration:
266+
267+
```json
268+
{
269+
"mcpServers": {
270+
"sysdig-mcp-server": {
271+
"command": "docker",
272+
"args": [
273+
"run",
274+
"-i",
275+
"--rm",
276+
"-e",
277+
"SYSDIG_HOST",
278+
"-e",
279+
"MCP_TRANSPORT",
280+
"-e",
281+
"SYSDIG_SECURE_TOKEN",
282+
"ghcr.io/sysdiglabs/sysdig-mcp-server"
283+
],
284+
"env": {
285+
"SYSDIG_HOST": "<your_sysdig_host>",
286+
"SYSDIG_SECURE_TOKEN": "<your_sysdig_secure_api_token>",
258287
"MCP_TRANSPORT": "stdio"
259288
}
260289
}

main.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@
1717

1818
app_config = get_app_config()
1919

20-
if __name__ == "__main__":
20+
21+
def main():
2122
# Choose transport: "stdio" or "sse" (HTTP/SSE)
2223
transport = os.environ.get("MCP_TRANSPORT", app_config["mcp"]["transport"]).lower()
2324
print("""
@@ -32,3 +33,7 @@
3233
else:
3334
# Run MCP server over streamable HTTP by default
3435
run_http()
36+
37+
38+
if __name__ == "__main__":
39+
main()

0 commit comments

Comments
 (0)