ocm-mcp-server 0.2.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ocm_mcp_server-0.2.2/.github/CODEOWNERS +2 -0
- ocm_mcp_server-0.2.2/.github/FUNDING.yml +5 -0
- ocm_mcp_server-0.2.2/.github/ISSUE_TEMPLATE/bug_report.md +38 -0
- ocm_mcp_server-0.2.2/.github/ISSUE_TEMPLATE/bug_report.yml +50 -0
- ocm_mcp_server-0.2.2/.github/ISSUE_TEMPLATE/config.yml +8 -0
- ocm_mcp_server-0.2.2/.github/ISSUE_TEMPLATE/custom.md +10 -0
- ocm_mcp_server-0.2.2/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- ocm_mcp_server-0.2.2/.github/ISSUE_TEMPLATE/feature_request.yml +25 -0
- ocm_mcp_server-0.2.2/.github/PULL_REQUEST_TEMPLATE.md +19 -0
- ocm_mcp_server-0.2.2/.github/dependabot.yml +23 -0
- ocm_mcp_server-0.2.2/.github/workflows/ci.yaml +88 -0
- ocm_mcp_server-0.2.2/.github/workflows/codeql.yml +101 -0
- ocm_mcp_server-0.2.2/.github/workflows/publish-image.yaml +100 -0
- ocm_mcp_server-0.2.2/.github/workflows/release.yaml +99 -0
- ocm_mcp_server-0.2.2/.github/workflows/scorecard.yml +47 -0
- ocm_mcp_server-0.2.2/.gitignore +26 -0
- ocm_mcp_server-0.2.2/ADOPTERS.md +27 -0
- ocm_mcp_server-0.2.2/CHANGELOG.md +281 -0
- ocm_mcp_server-0.2.2/CODE_OF_CONDUCT.md +29 -0
- ocm_mcp_server-0.2.2/CONTRIBUTING.md +47 -0
- ocm_mcp_server-0.2.2/Dockerfile +27 -0
- ocm_mcp_server-0.2.2/GOVERNANCE.md +75 -0
- ocm_mcp_server-0.2.2/LICENSE +202 -0
- ocm_mcp_server-0.2.2/MAINTAINERS.md +21 -0
- ocm_mcp_server-0.2.2/Makefile +63 -0
- ocm_mcp_server-0.2.2/PKG-INFO +647 -0
- ocm_mcp_server-0.2.2/README.md +624 -0
- ocm_mcp_server-0.2.2/ROADMAP.md +80 -0
- ocm_mcp_server-0.2.2/SECURITY.md +27 -0
- ocm_mcp_server-0.2.2/SUPPORT.md +24 -0
- ocm_mcp_server-0.2.2/chaos/inject.sh +32 -0
- ocm_mcp_server-0.2.2/chaos/scenarios/broken-service.sh +12 -0
- ocm_mcp_server-0.2.2/chaos/scenarios/config-drift.sh +11 -0
- ocm_mcp_server-0.2.2/chaos/scenarios/crashloop.sh +16 -0
- ocm_mcp_server-0.2.2/chaos/scenarios/failing-rollout.sh +35 -0
- ocm_mcp_server-0.2.2/chaos/scenarios/oom-loop.sh +10 -0
- ocm_mcp_server-0.2.2/chaos/scenarios/quota-exhaustion.sh +18 -0
- ocm_mcp_server-0.2.2/chaos/scenarios/scaled-to-zero.sh +8 -0
- ocm_mcp_server-0.2.2/demo/README.md +16 -0
- ocm_mcp_server-0.2.2/demo/demo.gif +0 -0
- ocm_mcp_server-0.2.2/deploy/charts/ocm-mcp-server/Chart.yaml +13 -0
- ocm_mcp_server-0.2.2/deploy/charts/ocm-mcp-server/templates/deployment.yaml +64 -0
- ocm_mcp_server-0.2.2/deploy/charts/ocm-mcp-server/templates/networkpolicy.yaml +22 -0
- ocm_mcp_server-0.2.2/deploy/charts/ocm-mcp-server/templates/pdb.yaml +12 -0
- ocm_mcp_server-0.2.2/deploy/charts/ocm-mcp-server/templates/pvc.yaml +17 -0
- ocm_mcp_server-0.2.2/deploy/charts/ocm-mcp-server/values.yaml +34 -0
- ocm_mcp_server-0.2.2/deploy/deployment.yaml +87 -0
- ocm_mcp_server-0.2.2/deploy/policies/disallow-privileged-manifestwork.yaml +67 -0
- ocm_mcp_server-0.2.2/deploy/policies/protect-system-namespaces.yaml +55 -0
- ocm_mcp_server-0.2.2/deploy/policies/require-managed-by-label.yaml +43 -0
- ocm_mcp_server-0.2.2/deploy/policies/restrict-manifestwork-kinds.yaml +74 -0
- ocm_mcp_server-0.2.2/deploy/policies/restrict-manifestwork-pod-security.yaml +135 -0
- ocm_mcp_server-0.2.2/deploy/policies/tests/kyverno-test.yaml +101 -0
- ocm_mcp_server-0.2.2/deploy/policies/tests/resources.yaml +338 -0
- ocm_mcp_server-0.2.2/deploy/policies/tests/userinfo.yaml +13 -0
- ocm_mcp_server-0.2.2/deploy/rbac.yaml +103 -0
- ocm_mcp_server-0.2.2/docs/_config.yml +6 -0
- ocm_mcp_server-0.2.2/docs/architecture.md +71 -0
- ocm_mcp_server-0.2.2/docs/assets/architecture-flow.gif +0 -0
- ocm_mcp_server-0.2.2/docs/assets/banner.svg +64 -0
- ocm_mcp_server-0.2.2/docs/assets/deploy-paths.svg +27 -0
- ocm_mcp_server-0.2.2/docs/assets/guardrails-flow.svg +79 -0
- ocm_mcp_server-0.2.2/docs/assets/read-write-paths.svg +40 -0
- ocm_mcp_server-0.2.2/docs/cncf-sandbox-readiness.md +65 -0
- ocm_mcp_server-0.2.2/docs/demo-script.md +50 -0
- ocm_mcp_server-0.2.2/docs/deployment.md +210 -0
- ocm_mcp_server-0.2.2/docs/examples.md +133 -0
- ocm_mcp_server-0.2.2/docs/guardrails.md +72 -0
- ocm_mcp_server-0.2.2/docs/index.md +45 -0
- ocm_mcp_server-0.2.2/docs/kubeconfig-contexts.md +148 -0
- ocm_mcp_server-0.2.2/docs/security-self-assessment.md +197 -0
- ocm_mcp_server-0.2.2/docs/tools.md +185 -0
- ocm_mcp_server-0.2.2/docs/upstream-notes.md +38 -0
- ocm_mcp_server-0.2.2/eval/README.md +28 -0
- ocm_mcp_server-0.2.2/eval/run_eval.py +171 -0
- ocm_mcp_server-0.2.2/eval/scenarios.yaml +172 -0
- ocm_mcp_server-0.2.2/examples/claude-code.mcp.json +12 -0
- ocm_mcp_server-0.2.2/examples/codex-config.toml +10 -0
- ocm_mcp_server-0.2.2/examples/gemini-settings.json +12 -0
- ocm_mcp_server-0.2.2/examples/generic-mcp.json +12 -0
- ocm_mcp_server-0.2.2/examples/system-prompt.md +37 -0
- ocm_mcp_server-0.2.2/hack/bootstrap.sh +176 -0
- ocm_mcp_server-0.2.2/hack/ci-local.sh +35 -0
- ocm_mcp_server-0.2.2/hack/demo-app.yaml +55 -0
- ocm_mcp_server-0.2.2/hack/e2e-local.sh +303 -0
- ocm_mcp_server-0.2.2/hack/e2e_report.py +298 -0
- ocm_mcp_server-0.2.2/hack/e2e_tools.py +397 -0
- ocm_mcp_server-0.2.2/hack/githooks/pre-push +9 -0
- ocm_mcp_server-0.2.2/hack/publish-wiki.sh +40 -0
- ocm_mcp_server-0.2.2/hack/teardown.sh +34 -0
- ocm_mcp_server-0.2.2/hack/unit_report.py +142 -0
- ocm_mcp_server-0.2.2/pyproject.toml +79 -0
- ocm_mcp_server-0.2.2/requirements.lock +1436 -0
- ocm_mcp_server-0.2.2/server.json +45 -0
- ocm_mcp_server-0.2.2/src/ocm_mcp_server/__init__.py +10 -0
- ocm_mcp_server-0.2.2/src/ocm_mcp_server/approvals.py +434 -0
- ocm_mcp_server-0.2.2/src/ocm_mcp_server/cli.py +243 -0
- ocm_mcp_server-0.2.2/src/ocm_mcp_server/config.py +332 -0
- ocm_mcp_server-0.2.2/src/ocm_mcp_server/filelock.py +40 -0
- ocm_mcp_server-0.2.2/src/ocm_mcp_server/guardrails.py +307 -0
- ocm_mcp_server-0.2.2/src/ocm_mcp_server/k8s.py +82 -0
- ocm_mcp_server-0.2.2/src/ocm_mcp_server/metrics.py +84 -0
- ocm_mcp_server-0.2.2/src/ocm_mcp_server/ocm.py +1095 -0
- ocm_mcp_server-0.2.2/src/ocm_mcp_server/server.py +975 -0
- ocm_mcp_server-0.2.2/src/ocm_mcp_server/tracing.py +231 -0
- ocm_mcp_server-0.2.2/tests/__init__.py +7 -0
- ocm_mcp_server-0.2.2/tests/conftest.py +18 -0
- ocm_mcp_server-0.2.2/tests/test_actions.py +65 -0
- ocm_mcp_server-0.2.2/tests/test_approvals.py +163 -0
- ocm_mcp_server-0.2.2/tests/test_cli.py +189 -0
- ocm_mcp_server-0.2.2/tests/test_cli_coverage.py +185 -0
- ocm_mcp_server-0.2.2/tests/test_csr.py +208 -0
- ocm_mcp_server-0.2.2/tests/test_guardrails.py +525 -0
- ocm_mcp_server-0.2.2/tests/test_hardening.py +337 -0
- ocm_mcp_server-0.2.2/tests/test_hcp_addons.py +79 -0
- ocm_mcp_server-0.2.2/tests/test_k8s.py +53 -0
- ocm_mcp_server-0.2.2/tests/test_metrics.py +63 -0
- ocm_mcp_server-0.2.2/tests/test_ocm.py +472 -0
- ocm_mcp_server-0.2.2/tests/test_ocm_coverage.py +420 -0
- ocm_mcp_server-0.2.2/tests/test_reader.py +69 -0
- ocm_mcp_server-0.2.2/tests/test_server.py +606 -0
- ocm_mcp_server-0.2.2/tests/test_small_coverage.py +37 -0
- ocm_mcp_server-0.2.2/tests/test_tracing.py +61 -0
- ocm_mcp_server-0.2.2/tests/test_tracing_coverage.py +252 -0
- ocm_mcp_server-0.2.2/wiki/Contributing.md +70 -0
- ocm_mcp_server-0.2.2/wiki/Evaluation.md +76 -0
- ocm_mcp_server-0.2.2/wiki/FAQ.md +60 -0
- ocm_mcp_server-0.2.2/wiki/Getting-Started.md +72 -0
- ocm_mcp_server-0.2.2/wiki/Guardrails-Deep-Dive.md +114 -0
- ocm_mcp_server-0.2.2/wiki/Home.md +56 -0
- ocm_mcp_server-0.2.2/wiki/How-It-Works.md +120 -0
- ocm_mcp_server-0.2.2/wiki/Implementation.md +164 -0
- ocm_mcp_server-0.2.2/wiki/Roadmap.md +62 -0
- ocm_mcp_server-0.2.2/wiki/Test-Results.md +1189 -0
- ocm_mcp_server-0.2.2/wiki/The-Idea.md +55 -0
- ocm_mcp_server-0.2.2/wiki/Tools-and-Prompts.md +123 -0
- ocm_mcp_server-0.2.2/wiki/Unit-Test-Results.md +31 -0
- ocm_mcp_server-0.2.2/wiki/Use-Cases-and-Impact.md +58 -0
- ocm_mcp_server-0.2.2/wiki/Why-This-Exists.md +57 -0
- ocm_mcp_server-0.2.2/wiki/_Footer.md +4 -0
- ocm_mcp_server-0.2.2/wiki/_Sidebar.md +23 -0
- ocm_mcp_server-0.2.2/wiki/coverage-badge.json +1 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Bug report
|
|
3
|
+
about: Create a report to help us improve
|
|
4
|
+
title: ''
|
|
5
|
+
labels: ''
|
|
6
|
+
assignees: ''
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
**Describe the bug**
|
|
11
|
+
A clear and concise description of what the bug is.
|
|
12
|
+
|
|
13
|
+
**To Reproduce**
|
|
14
|
+
Steps to reproduce the behavior:
|
|
15
|
+
1. Go to '...'
|
|
16
|
+
2. Click on '....'
|
|
17
|
+
3. Scroll down to '....'
|
|
18
|
+
4. See error
|
|
19
|
+
|
|
20
|
+
**Expected behavior**
|
|
21
|
+
A clear and concise description of what you expected to happen.
|
|
22
|
+
|
|
23
|
+
**Screenshots**
|
|
24
|
+
If applicable, add screenshots to help explain your problem.
|
|
25
|
+
|
|
26
|
+
**Desktop (please complete the following information):**
|
|
27
|
+
- OS: [e.g. iOS]
|
|
28
|
+
- Browser [e.g. chrome, safari]
|
|
29
|
+
- Version [e.g. 22]
|
|
30
|
+
|
|
31
|
+
**Smartphone (please complete the following information):**
|
|
32
|
+
- Device: [e.g. iPhone6]
|
|
33
|
+
- OS: [e.g. iOS8.1]
|
|
34
|
+
- Browser [e.g. stock browser, safari]
|
|
35
|
+
- Version [e.g. 22]
|
|
36
|
+
|
|
37
|
+
**Additional context**
|
|
38
|
+
Add any other context about the problem here.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
name: Bug report
|
|
2
|
+
description: Something is broken or behaving unexpectedly
|
|
3
|
+
labels: ["bug"]
|
|
4
|
+
body:
|
|
5
|
+
- type: textarea
|
|
6
|
+
id: what
|
|
7
|
+
attributes:
|
|
8
|
+
label: What happened
|
|
9
|
+
description: What did you do, what did you expect, what happened instead?
|
|
10
|
+
validations:
|
|
11
|
+
required: true
|
|
12
|
+
- type: textarea
|
|
13
|
+
id: repro
|
|
14
|
+
attributes:
|
|
15
|
+
label: Reproduction steps
|
|
16
|
+
placeholder: |
|
|
17
|
+
1. make bootstrap
|
|
18
|
+
2. make inject SCENARIO=... CLUSTER=...
|
|
19
|
+
3. tool call / prompt that triggered it
|
|
20
|
+
validations:
|
|
21
|
+
required: true
|
|
22
|
+
- type: dropdown
|
|
23
|
+
id: area
|
|
24
|
+
attributes:
|
|
25
|
+
label: Area
|
|
26
|
+
options:
|
|
27
|
+
- MCP tools / server
|
|
28
|
+
- Guardrails (static checks)
|
|
29
|
+
- Kyverno policies
|
|
30
|
+
- Approval flow / CLI
|
|
31
|
+
- Bootstrap / fleet setup
|
|
32
|
+
- Chaos scenarios
|
|
33
|
+
- Eval harness
|
|
34
|
+
- Docs
|
|
35
|
+
validations:
|
|
36
|
+
required: true
|
|
37
|
+
- type: textarea
|
|
38
|
+
id: env
|
|
39
|
+
attributes:
|
|
40
|
+
label: Environment
|
|
41
|
+
placeholder: |
|
|
42
|
+
OS, Python version, kind/OCM/Kyverno versions, MCP client used
|
|
43
|
+
validations:
|
|
44
|
+
required: true
|
|
45
|
+
- type: textarea
|
|
46
|
+
id: logs
|
|
47
|
+
attributes:
|
|
48
|
+
label: Relevant output
|
|
49
|
+
description: Server output, `ocm-mcp audit` lines, or policy messages. Redact tokens and cluster names as needed.
|
|
50
|
+
render: shell
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
blank_issues_enabled: false
|
|
2
|
+
contact_links:
|
|
3
|
+
- name: Security vulnerability
|
|
4
|
+
url: https://github.com/sandeepbazar/ocm-mcp-server/security/advisories/new
|
|
5
|
+
about: Report privately via a security advisory - never in a public issue.
|
|
6
|
+
- name: Commercial support / sponsorship
|
|
7
|
+
url: https://github.com/sandeepbazar/ocm-mcp-server/blob/main/SUPPORT.md
|
|
8
|
+
about: See SUPPORT.md - enquiries via LinkedIn
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Feature request
|
|
3
|
+
about: Suggest an idea for this project
|
|
4
|
+
title: ''
|
|
5
|
+
labels: ''
|
|
6
|
+
assignees: ''
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
**Is your feature request related to a problem? Please describe.**
|
|
11
|
+
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
|
12
|
+
|
|
13
|
+
**Describe the solution you'd like**
|
|
14
|
+
A clear and concise description of what you want to happen.
|
|
15
|
+
|
|
16
|
+
**Describe alternatives you've considered**
|
|
17
|
+
A clear and concise description of any alternative solutions or features you've considered.
|
|
18
|
+
|
|
19
|
+
**Additional context**
|
|
20
|
+
Add any other context or screenshots about the feature request here.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
name: Feature request
|
|
2
|
+
description: Propose an improvement or new capability
|
|
3
|
+
labels: ["enhancement"]
|
|
4
|
+
body:
|
|
5
|
+
- type: textarea
|
|
6
|
+
id: problem
|
|
7
|
+
attributes:
|
|
8
|
+
label: Problem
|
|
9
|
+
description: What can't you do today, or what is harder than it should be?
|
|
10
|
+
validations:
|
|
11
|
+
required: true
|
|
12
|
+
- type: textarea
|
|
13
|
+
id: proposal
|
|
14
|
+
attributes:
|
|
15
|
+
label: Proposed solution
|
|
16
|
+
validations:
|
|
17
|
+
required: true
|
|
18
|
+
- type: textarea
|
|
19
|
+
id: safety
|
|
20
|
+
attributes:
|
|
21
|
+
label: Safety considerations (required for new MCP tools)
|
|
22
|
+
description: >
|
|
23
|
+
This project keeps the tool surface deliberately small. If you are
|
|
24
|
+
proposing a new tool or a wider write path, explain why it is safe to
|
|
25
|
+
expose and which guardrail layers cover it (see CONTRIBUTING.md).
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
## What
|
|
2
|
+
|
|
3
|
+
<!-- One or two sentences: what does this PR change? -->
|
|
4
|
+
|
|
5
|
+
## Why
|
|
6
|
+
|
|
7
|
+
<!-- Link the issue if one exists: Fixes #NN -->
|
|
8
|
+
|
|
9
|
+
## How was it verified
|
|
10
|
+
|
|
11
|
+
- [ ] `make test` passes
|
|
12
|
+
- [ ] `make lint` passes
|
|
13
|
+
- [ ] For write-path / guardrail changes: new or updated tests cover the behavior
|
|
14
|
+
- [ ] For new MCP tools: safety rationale included (see CONTRIBUTING.md)
|
|
15
|
+
- [ ] Commits are signed off (`git commit -s`, DCO)
|
|
16
|
+
|
|
17
|
+
## Notes for the reviewer
|
|
18
|
+
|
|
19
|
+
<!-- Anything non-obvious: trade-offs, follow-ups, screenshots of demo output -->
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2026 Sandeep Bazar
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
# Keep GitHub Actions and Python dependencies current. Action pins can move under
|
|
4
|
+
# tags, so Dependabot proposes updates (and their new SHAs) on a schedule.
|
|
5
|
+
version: 2
|
|
6
|
+
updates:
|
|
7
|
+
- package-ecosystem: github-actions
|
|
8
|
+
directory: "/"
|
|
9
|
+
schedule:
|
|
10
|
+
interval: weekly
|
|
11
|
+
open-pull-requests-limit: 5
|
|
12
|
+
|
|
13
|
+
- package-ecosystem: pip
|
|
14
|
+
directory: "/"
|
|
15
|
+
schedule:
|
|
16
|
+
interval: weekly
|
|
17
|
+
open-pull-requests-limit: 5
|
|
18
|
+
|
|
19
|
+
- package-ecosystem: docker
|
|
20
|
+
directory: "/"
|
|
21
|
+
schedule:
|
|
22
|
+
interval: weekly
|
|
23
|
+
open-pull-requests-limit: 5
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2026 Sandeep Bazar
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
name: ci
|
|
5
|
+
|
|
6
|
+
on:
|
|
7
|
+
push:
|
|
8
|
+
branches: [main]
|
|
9
|
+
pull_request:
|
|
10
|
+
|
|
11
|
+
# Least privilege by default: jobs that need more request it explicitly.
|
|
12
|
+
permissions:
|
|
13
|
+
contents: read
|
|
14
|
+
|
|
15
|
+
jobs:
|
|
16
|
+
test:
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
strategy:
|
|
19
|
+
matrix:
|
|
20
|
+
python-version: ["3.11", "3.12", "3.13", "3.14"]
|
|
21
|
+
steps:
|
|
22
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
23
|
+
with:
|
|
24
|
+
persist-credentials: false
|
|
25
|
+
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
|
26
|
+
with:
|
|
27
|
+
python-version: ${{ matrix.python-version }}
|
|
28
|
+
- name: Install
|
|
29
|
+
run: pip install -e ".[dev]"
|
|
30
|
+
- name: Lint
|
|
31
|
+
run: ruff check src tests eval hack
|
|
32
|
+
- name: Format check
|
|
33
|
+
run: ruff format --check src tests eval
|
|
34
|
+
- name: Type check
|
|
35
|
+
run: mypy
|
|
36
|
+
- name: Unit tests + coverage gate
|
|
37
|
+
run: pytest -q --cov=ocm_mcp_server --cov-report=term-missing --cov-fail-under=95
|
|
38
|
+
- name: Shell syntax
|
|
39
|
+
run: bash -n hack/*.sh chaos/inject.sh chaos/scenarios/*.sh
|
|
40
|
+
- name: Unit-test report + browsable coverage HTML (one matrix leg only)
|
|
41
|
+
if: matrix.python-version == '3.12'
|
|
42
|
+
run: make test-report
|
|
43
|
+
- name: Upload unit-test + coverage report
|
|
44
|
+
if: matrix.python-version == '3.12'
|
|
45
|
+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
46
|
+
with:
|
|
47
|
+
name: unit-test-report
|
|
48
|
+
path: |
|
|
49
|
+
.unit-report/htmlcov
|
|
50
|
+
.unit-report/junit.xml
|
|
51
|
+
wiki/Unit-Test-Results.md
|
|
52
|
+
wiki/coverage-badge.json
|
|
53
|
+
retention-days: 30
|
|
54
|
+
|
|
55
|
+
policy-test:
|
|
56
|
+
runs-on: ubuntu-latest
|
|
57
|
+
steps:
|
|
58
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
59
|
+
with:
|
|
60
|
+
persist-credentials: false
|
|
61
|
+
- name: Install Kyverno CLI
|
|
62
|
+
uses: kyverno/action-install-cli@fcee92fca5c883169ef9927acf543e0b5fc58289 # v0.2.0
|
|
63
|
+
with:
|
|
64
|
+
release: v1.18.2
|
|
65
|
+
- name: Offline policy tests
|
|
66
|
+
run: kyverno test deploy/policies/tests
|
|
67
|
+
|
|
68
|
+
dependency-review:
|
|
69
|
+
# Flags known-vulnerable or disallowed-license dependencies added in a PR.
|
|
70
|
+
runs-on: ubuntu-latest
|
|
71
|
+
if: github.event_name == 'pull_request'
|
|
72
|
+
steps:
|
|
73
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
74
|
+
with:
|
|
75
|
+
persist-credentials: false
|
|
76
|
+
- uses: actions/dependency-review-action@a1d282b36b6f3519aa1f3fc636f609c47dddb294 # v5.0.0
|
|
77
|
+
|
|
78
|
+
secret-scan:
|
|
79
|
+
runs-on: ubuntu-latest
|
|
80
|
+
steps:
|
|
81
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
82
|
+
with:
|
|
83
|
+
persist-credentials: false
|
|
84
|
+
fetch-depth: 0
|
|
85
|
+
- name: gitleaks
|
|
86
|
+
uses: gitleaks/gitleaks-action@ff98106e4c7b2bc287b24eaf42907196329070c7 # v2
|
|
87
|
+
env:
|
|
88
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# For most projects, this workflow file will not need changing; you simply need
|
|
2
|
+
# to commit it to your repository.
|
|
3
|
+
#
|
|
4
|
+
# You may wish to alter this file to override the set of languages analyzed,
|
|
5
|
+
# or to provide custom queries or build logic.
|
|
6
|
+
#
|
|
7
|
+
# ******** NOTE ********
|
|
8
|
+
# We have attempted to detect the languages in your repository. Please check
|
|
9
|
+
# the `language` matrix defined below to confirm you have the correct set of
|
|
10
|
+
# supported CodeQL languages.
|
|
11
|
+
#
|
|
12
|
+
name: "CodeQL Advanced"
|
|
13
|
+
|
|
14
|
+
on:
|
|
15
|
+
push:
|
|
16
|
+
branches: [ "main" ]
|
|
17
|
+
pull_request:
|
|
18
|
+
branches: [ "main" ]
|
|
19
|
+
schedule:
|
|
20
|
+
- cron: '43 2 * * 6'
|
|
21
|
+
|
|
22
|
+
jobs:
|
|
23
|
+
analyze:
|
|
24
|
+
name: Analyze (${{ matrix.language }})
|
|
25
|
+
# Runner size impacts CodeQL analysis time. To learn more, please see:
|
|
26
|
+
# - https://gh.io/recommended-hardware-resources-for-running-codeql
|
|
27
|
+
# - https://gh.io/supported-runners-and-hardware-resources
|
|
28
|
+
# - https://gh.io/using-larger-runners (GitHub.com only)
|
|
29
|
+
# Consider using larger runners or machines with greater resources for possible analysis time improvements.
|
|
30
|
+
runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
|
|
31
|
+
permissions:
|
|
32
|
+
# required for all workflows
|
|
33
|
+
security-events: write
|
|
34
|
+
|
|
35
|
+
# required to fetch internal or private CodeQL packs
|
|
36
|
+
packages: read
|
|
37
|
+
|
|
38
|
+
# only required for workflows in private repositories
|
|
39
|
+
actions: read
|
|
40
|
+
contents: read
|
|
41
|
+
|
|
42
|
+
strategy:
|
|
43
|
+
fail-fast: false
|
|
44
|
+
matrix:
|
|
45
|
+
include:
|
|
46
|
+
- language: actions
|
|
47
|
+
build-mode: none
|
|
48
|
+
- language: python
|
|
49
|
+
build-mode: none
|
|
50
|
+
# CodeQL supports the following values keywords for 'language': 'actions', 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'rust', 'swift'
|
|
51
|
+
# Use `c-cpp` to analyze code written in C, C++ or both
|
|
52
|
+
# Use 'java-kotlin' to analyze code written in Java, Kotlin or both
|
|
53
|
+
# Use 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both
|
|
54
|
+
# To learn more about changing the languages that are analyzed or customizing the build mode for your analysis,
|
|
55
|
+
# see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning.
|
|
56
|
+
# If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how
|
|
57
|
+
# your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages
|
|
58
|
+
steps:
|
|
59
|
+
- name: Checkout repository
|
|
60
|
+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
61
|
+
|
|
62
|
+
# Add any setup steps before running the `github/codeql-action/init` action.
|
|
63
|
+
# This includes steps like installing compilers or runtimes (`actions/setup-node`
|
|
64
|
+
# or others). This is typically only required for manual builds.
|
|
65
|
+
# - name: Setup runtime (example)
|
|
66
|
+
# uses: actions/setup-example@v1
|
|
67
|
+
|
|
68
|
+
# Initializes the CodeQL tools for scanning.
|
|
69
|
+
- name: Initialize CodeQL
|
|
70
|
+
uses: github/codeql-action/init@e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81 # v4
|
|
71
|
+
with:
|
|
72
|
+
languages: ${{ matrix.language }}
|
|
73
|
+
build-mode: ${{ matrix.build-mode }}
|
|
74
|
+
# If you wish to specify custom queries, you can do so here or in a config file.
|
|
75
|
+
# By default, queries listed here will override any specified in a config file.
|
|
76
|
+
# Prefix the list here with "+" to use these queries and those in the config file.
|
|
77
|
+
|
|
78
|
+
# For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
|
|
79
|
+
# queries: security-extended,security-and-quality
|
|
80
|
+
|
|
81
|
+
# If the analyze step fails for one of the languages you are analyzing with
|
|
82
|
+
# "We were unable to automatically build your code", modify the matrix above
|
|
83
|
+
# to set the build mode to "manual" for that language. Then modify this step
|
|
84
|
+
# to build your code.
|
|
85
|
+
# ℹ️ Command-line programs to run using the OS shell.
|
|
86
|
+
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
|
87
|
+
- name: Run manual build steps
|
|
88
|
+
if: matrix.build-mode == 'manual'
|
|
89
|
+
shell: bash
|
|
90
|
+
run: |
|
|
91
|
+
echo 'If you are using a "manual" build mode for one or more of the' \
|
|
92
|
+
'languages you are analyzing, replace this with the commands to build' \
|
|
93
|
+
'your code, for example:'
|
|
94
|
+
echo ' make bootstrap'
|
|
95
|
+
echo ' make release'
|
|
96
|
+
exit 1
|
|
97
|
+
|
|
98
|
+
- name: Perform CodeQL Analysis
|
|
99
|
+
uses: github/codeql-action/analyze@e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81 # v4
|
|
100
|
+
with:
|
|
101
|
+
category: "/language:${{matrix.language}}"
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2026 Sandeep Bazar
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
#
|
|
4
|
+
# Build and publish the container image to ghcr.io on every v* tag push, with an SBOM,
|
|
5
|
+
# build provenance, a keyless Cosign signature, and a vulnerability scan. It triggers on
|
|
6
|
+
# the tag push (NOT release:published) because a Release created by the built-in
|
|
7
|
+
# GITHUB_TOKEN does not start other workflows - so the image is guaranteed to build for
|
|
8
|
+
# every tagged release. Uses GITHUB_TOKEN and OIDC only; no external credentials.
|
|
9
|
+
name: publish-image
|
|
10
|
+
|
|
11
|
+
on:
|
|
12
|
+
push:
|
|
13
|
+
tags:
|
|
14
|
+
- "v*"
|
|
15
|
+
workflow_dispatch:
|
|
16
|
+
|
|
17
|
+
permissions:
|
|
18
|
+
contents: read
|
|
19
|
+
packages: write
|
|
20
|
+
id-token: write # keyless Cosign signing via OIDC
|
|
21
|
+
attestations: write # build provenance attestation
|
|
22
|
+
|
|
23
|
+
jobs:
|
|
24
|
+
image:
|
|
25
|
+
runs-on: ubuntu-latest
|
|
26
|
+
steps:
|
|
27
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
28
|
+
with:
|
|
29
|
+
persist-credentials: false
|
|
30
|
+
|
|
31
|
+
- name: Set up Docker Buildx
|
|
32
|
+
# The runner's default (docker-driver) builder cannot produce SBOM or
|
|
33
|
+
# provenance attestations, nor index-level annotations; the
|
|
34
|
+
# docker-container driver can.
|
|
35
|
+
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0
|
|
36
|
+
|
|
37
|
+
- name: Log in to ghcr.io
|
|
38
|
+
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3
|
|
39
|
+
with:
|
|
40
|
+
registry: ghcr.io
|
|
41
|
+
username: ${{ github.actor }}
|
|
42
|
+
password: ${{ github.token }}
|
|
43
|
+
|
|
44
|
+
- name: Image metadata (tags + labels)
|
|
45
|
+
id: meta
|
|
46
|
+
uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6.2.0
|
|
47
|
+
with:
|
|
48
|
+
images: ghcr.io/${{ github.repository }}
|
|
49
|
+
tags: |
|
|
50
|
+
type=semver,pattern={{version}}
|
|
51
|
+
type=raw,value=latest
|
|
52
|
+
|
|
53
|
+
- name: Build and push (with SBOM + provenance)
|
|
54
|
+
id: build
|
|
55
|
+
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6
|
|
56
|
+
with:
|
|
57
|
+
context: .
|
|
58
|
+
push: true
|
|
59
|
+
tags: ${{ steps.meta.outputs.tags }}
|
|
60
|
+
labels: ${{ steps.meta.outputs.labels }}
|
|
61
|
+
sbom: true
|
|
62
|
+
provenance: mode=max
|
|
63
|
+
# Ownership-verification marker for the official MCP Registry
|
|
64
|
+
# (registry.modelcontextprotocol.io): proves this image backs the
|
|
65
|
+
# server named io.github.sandeepbazar/ocm-mcp-server.
|
|
66
|
+
annotations: |
|
|
67
|
+
index,manifest:io.modelcontextprotocol.server.name=io.github.sandeepbazar/ocm-mcp-server
|
|
68
|
+
|
|
69
|
+
- name: Scan the published image for vulnerabilities
|
|
70
|
+
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0
|
|
71
|
+
with:
|
|
72
|
+
image-ref: "ghcr.io/${{ github.repository }}@${{ steps.build.outputs.digest }}"
|
|
73
|
+
format: table
|
|
74
|
+
exit-code: "1"
|
|
75
|
+
ignore-unfixed: true
|
|
76
|
+
severity: HIGH,CRITICAL
|
|
77
|
+
|
|
78
|
+
- name: Install Cosign
|
|
79
|
+
uses: sigstore/cosign-installer@398d4b0eeef1380460a10c8013a76f728fb906ac # v3
|
|
80
|
+
|
|
81
|
+
- name: Sign the pushed image (keyless)
|
|
82
|
+
env:
|
|
83
|
+
DIGEST: ${{ steps.build.outputs.digest }}
|
|
84
|
+
run: cosign sign --yes "ghcr.io/${{ github.repository }}@${DIGEST}"
|
|
85
|
+
|
|
86
|
+
- name: Attest build provenance
|
|
87
|
+
uses: actions/attest-build-provenance@ef244123eb79f2f7a7e75d99086184180e6d0018 # v1
|
|
88
|
+
with:
|
|
89
|
+
subject-name: ghcr.io/${{ github.repository }}
|
|
90
|
+
subject-digest: ${{ steps.build.outputs.digest }}
|
|
91
|
+
push-to-registry: true
|
|
92
|
+
|
|
93
|
+
- name: Verify the signature we just created
|
|
94
|
+
env:
|
|
95
|
+
DIGEST: ${{ steps.build.outputs.digest }}
|
|
96
|
+
run: |
|
|
97
|
+
cosign verify \
|
|
98
|
+
--certificate-identity-regexp "^https://github.com/${{ github.repository }}/" \
|
|
99
|
+
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
|
|
100
|
+
"ghcr.io/${{ github.repository }}@${DIGEST}"
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2026 Sandeep Bazar
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
#
|
|
4
|
+
# Create a GitHub Release automatically whenever a v* tag is pushed.
|
|
5
|
+
# Fills the repository's Releases section with no manual step.
|
|
6
|
+
name: release
|
|
7
|
+
|
|
8
|
+
on:
|
|
9
|
+
push:
|
|
10
|
+
tags:
|
|
11
|
+
- "v*"
|
|
12
|
+
|
|
13
|
+
permissions:
|
|
14
|
+
contents: write
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
release:
|
|
18
|
+
runs-on: ubuntu-latest
|
|
19
|
+
steps:
|
|
20
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
21
|
+
- name: Create release from the tag
|
|
22
|
+
env:
|
|
23
|
+
GH_TOKEN: ${{ github.token }}
|
|
24
|
+
TAG: ${{ github.ref_name }}
|
|
25
|
+
run: |
|
|
26
|
+
# Idempotent, but a real failure still fails the job (not masked).
|
|
27
|
+
if gh release view "$TAG" >/dev/null 2>&1; then
|
|
28
|
+
echo "release for $TAG already exists"
|
|
29
|
+
exit 0
|
|
30
|
+
fi
|
|
31
|
+
gh release create "$TAG" \
|
|
32
|
+
--title "$TAG" \
|
|
33
|
+
--notes "See [CHANGELOG.md](https://github.com/${{ github.repository }}/blob/main/CHANGELOG.md) for the full list of changes in this release." \
|
|
34
|
+
--verify-tag
|
|
35
|
+
|
|
36
|
+
pypi:
|
|
37
|
+
# Publish sdist + wheel to PyPI via OIDC trusted publishing: no stored token,
|
|
38
|
+
# same keyless philosophy as the Cosign image signature.
|
|
39
|
+
# One-time setup on pypi.org: add this repo/workflow as a trusted publisher
|
|
40
|
+
# for the 'ocm-mcp-server' project (environment: pypi).
|
|
41
|
+
runs-on: ubuntu-latest
|
|
42
|
+
environment:
|
|
43
|
+
name: pypi
|
|
44
|
+
url: https://pypi.org/p/ocm-mcp-server
|
|
45
|
+
permissions:
|
|
46
|
+
contents: read
|
|
47
|
+
id-token: write # OIDC token for PyPI trusted publishing
|
|
48
|
+
steps:
|
|
49
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
50
|
+
with:
|
|
51
|
+
persist-credentials: false
|
|
52
|
+
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
|
53
|
+
with:
|
|
54
|
+
python-version: "3.12"
|
|
55
|
+
- name: Build sdist and wheel
|
|
56
|
+
run: |
|
|
57
|
+
python -m pip install --upgrade build
|
|
58
|
+
python -m build
|
|
59
|
+
- name: Publish to PyPI
|
|
60
|
+
# Tag pin, not SHA: this is a Docker-based action that resolves its
|
|
61
|
+
# container image from the git ref name, so hash-pinning breaks it
|
|
62
|
+
# (documented upstream). The tag is the strongest supported pin.
|
|
63
|
+
uses: pypa/gh-action-pypi-publish@v1.14.1
|
|
64
|
+
|
|
65
|
+
mcp-registry:
|
|
66
|
+
# Publish server metadata to the official MCP Registry
|
|
67
|
+
# (registry.modelcontextprotocol.io) after the PyPI package exists, since
|
|
68
|
+
# the registry validates the mcp-name ownership marker in the PyPI README.
|
|
69
|
+
needs: pypi
|
|
70
|
+
runs-on: ubuntu-latest
|
|
71
|
+
permissions:
|
|
72
|
+
contents: read
|
|
73
|
+
id-token: write # GitHub OIDC login to the MCP registry
|
|
74
|
+
steps:
|
|
75
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
76
|
+
with:
|
|
77
|
+
persist-credentials: false
|
|
78
|
+
- name: Install mcp-publisher
|
|
79
|
+
run: |
|
|
80
|
+
curl -fsSL "https://github.com/modelcontextprotocol/registry/releases/latest/download/mcp-publisher_$(uname -s | tr '[:upper:]' '[:lower:]')_$(uname -m).tar.gz" \
|
|
81
|
+
| tar xz mcp-publisher
|
|
82
|
+
- name: Stamp server.json version from the tag
|
|
83
|
+
env:
|
|
84
|
+
TAG: ${{ github.ref_name }}
|
|
85
|
+
run: |
|
|
86
|
+
v="${TAG#v}"
|
|
87
|
+
jq --arg v "$v" '.version = $v | (.packages[] | .version) = $v' server.json > server.json.tmp
|
|
88
|
+
mv server.json.tmp server.json
|
|
89
|
+
- name: Publish to the MCP Registry
|
|
90
|
+
run: |
|
|
91
|
+
./mcp-publisher login github-oidc
|
|
92
|
+
# The freshly published PyPI release can take a moment to be visible
|
|
93
|
+
# to the registry's validator; retry a few times before failing.
|
|
94
|
+
for attempt in 1 2 3 4 5; do
|
|
95
|
+
./mcp-publisher publish && exit 0
|
|
96
|
+
echo "publish attempt ${attempt} failed; retrying in 30s"
|
|
97
|
+
sleep 30
|
|
98
|
+
done
|
|
99
|
+
exit 1
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2026 Sandeep Bazar
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
#
|
|
4
|
+
# OpenSSF Scorecard: supply-chain security posture, published to the OpenSSF
|
|
5
|
+
# API (powers the README badge) and to the repo's Code Scanning dashboard.
|
|
6
|
+
# Template: https://github.com/ossf/scorecard/blob/main/.github/workflows/scorecard-analysis.yml
|
|
7
|
+
name: scorecard
|
|
8
|
+
|
|
9
|
+
on:
|
|
10
|
+
push:
|
|
11
|
+
branches: [main]
|
|
12
|
+
schedule:
|
|
13
|
+
- cron: "30 1 * * 6" # weekly, Saturdays
|
|
14
|
+
|
|
15
|
+
permissions: read-all
|
|
16
|
+
|
|
17
|
+
jobs:
|
|
18
|
+
analysis:
|
|
19
|
+
name: Scorecard analysis
|
|
20
|
+
runs-on: ubuntu-latest
|
|
21
|
+
permissions:
|
|
22
|
+
security-events: write # upload SARIF to code scanning
|
|
23
|
+
id-token: write # OIDC token verifies authenticity of published results
|
|
24
|
+
|
|
25
|
+
steps:
|
|
26
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
27
|
+
with:
|
|
28
|
+
persist-credentials: false
|
|
29
|
+
|
|
30
|
+
- name: Run analysis
|
|
31
|
+
uses: ossf/scorecard-action@55891bbd73f2425e97637d96e306fc9d491d0b21 # v2.4.4
|
|
32
|
+
with:
|
|
33
|
+
results_file: results.sarif
|
|
34
|
+
results_format: sarif
|
|
35
|
+
publish_results: true
|
|
36
|
+
|
|
37
|
+
- name: Upload SARIF artifact
|
|
38
|
+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
39
|
+
with:
|
|
40
|
+
name: scorecard-sarif
|
|
41
|
+
path: results.sarif
|
|
42
|
+
retention-days: 5
|
|
43
|
+
|
|
44
|
+
- name: Upload to code scanning
|
|
45
|
+
uses: github/codeql-action/upload-sarif@e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81 # v4
|
|
46
|
+
with:
|
|
47
|
+
sarif_file: results.sarif
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
__pycache__/
|
|
2
|
+
*.pyc
|
|
3
|
+
*.egg-info/
|
|
4
|
+
dist/
|
|
5
|
+
build/
|
|
6
|
+
.venv/
|
|
7
|
+
venv/
|
|
8
|
+
.pytest_cache/
|
|
9
|
+
.ruff_cache/
|
|
10
|
+
.ocm-mcp/
|
|
11
|
+
# real kubeconfig files only (not docs about kubeconfig)
|
|
12
|
+
/kubeconfig
|
|
13
|
+
*.kubeconfig
|
|
14
|
+
!examples/kubeconfig.example
|
|
15
|
+
eval/results/*.json
|
|
16
|
+
.DS_Store
|
|
17
|
+
# local end-to-end test output (generated by hack/e2e-local.sh) - never checked in
|
|
18
|
+
/e2e-report.html
|
|
19
|
+
/.e2e-run/
|
|
20
|
+
|
|
21
|
+
# coverage artifacts
|
|
22
|
+
.coverage
|
|
23
|
+
htmlcov/
|
|
24
|
+
|
|
25
|
+
# unit-test report artifacts (generated by make test-report) - never checked in
|
|
26
|
+
/.unit-report/
|