Skip to content

Commit fcff957

Browse files
author
Test
committed
docs: update OpenAPI spec, HTML dashboard, and architecture diagram
1 parent d13b447 commit fcff957

3 files changed

Lines changed: 96 additions & 42 deletions

File tree

README.md

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -119,26 +119,40 @@ Via environment variables:
119119
## Architecture
120120

121121
```
122-
Kubernetes API (read-only)
123-
|
124-
v
125-
+--------------+
126-
| deployscope |
127-
| |
128-
| K8s client |--> 30s cache
129-
| HTTP server |--> REST API + HTML
130-
| |
131-
+--------------+
132-
|
133-
v
134-
Browser / Grafana / CI
122+
deployscope CLI
123+
/ | \
124+
serve status doctor
125+
| | |
126+
v v v
127+
+---------------------------+
128+
| K8s client |
129+
| Deployments |
130+
| StatefulSets |
131+
| DaemonSets |
132+
| + annotation extraction |
133+
+---------------------------+
134+
| |
135+
30s cache deployscope.dev/*
136+
| annotations
137+
v
138+
+-------------------+
139+
| HTTP server |
140+
| |
141+
| REST API (/api/) |
142+
| HTML dashboard |
143+
| /metrics (prom) |
144+
| /health /ready |
145+
+-------------------+
146+
|
147+
v
148+
Browser / Grafana / Agents
135149
```
136150

137151
Cluster requirements:
138152
- Kubernetes >= 1.23
139-
- RBAC: read-only access to deployments and namespaces (see `deploy/rbac.yaml`)
153+
- RBAC: read-only access to deployments, statefulsets, daemonsets, namespaces (see `deploy/rbac.yaml`)
140154

141-
Only deployments with label `app.kubernetes.io/version` are monitored.
155+
Only workloads with label `app.kubernetes.io/version` are monitored.
142156

143157
## Agent-native interface
144158

internal/server/html.go

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,24 @@ func getHTMLPage() string {
1313
.method { display: inline-block; padding: 5px 10px; border-radius: 3px; font-weight: bold; }
1414
.get { background: #61affe; color: white; }
1515
code { background: #eee; padding: 2px 6px; border-radius: 3px; }
16+
.note { background: #e8f4e8; padding: 12px; border-radius: 5px; margin: 15px 0; }
1617
</style>
1718
</head>
1819
<body>
1920
<h1>DeployScope API v1</h1>
20-
<p>RESTful API for monitoring Kubernetes deployments</p>
21+
<p>RESTful API for monitoring Kubernetes workloads (Deployments, StatefulSets, DaemonSets)</p>
22+
23+
<div class="note">
24+
<strong>CLI available:</strong> <code>deployscope status --format json</code> for one-shot queries.
25+
See <code>deployscope --help</code> for all commands.
26+
</div>
2127
2228
<h2>Endpoints</h2>
2329
2430
<div class="endpoint">
2531
<span class="method get">GET</span>
2632
<strong>/api/v1/services</strong>
27-
<p>List all services with pagination, filtering, and sorting</p>
33+
<p>List all workloads with pagination, filtering, and sorting</p>
2834
<p><strong>Query parameters:</strong></p>
2935
<ul>
3036
<li><code>page</code> - page number (default: 1)</li>
@@ -33,16 +39,16 @@ func getHTMLPage() string {
3339
<li><code>status</code> - filter by status (green/yellow/red)</li>
3440
<li><code>name</code> - search by name (contains)</li>
3541
<li><code>version</code> - filter by version</li>
42+
<li><code>type</code> - filter by workload type (deployment/statefulset/daemonset)</li>
3643
<li><code>sort</code> - sort field (name, namespace, version, status, replicas; prefix "-" for desc)</li>
3744
</ul>
38-
<p><strong>Example:</strong> <code>/api/v1/services?namespace=production&amp;status=green&amp;page=1&amp;limit=50&amp;sort=-name</code></p>
45+
<p><strong>Example:</strong> <code>/api/v1/services?namespace=production&amp;status=green&amp;type=statefulset</code></p>
3946
</div>
4047
4148
<div class="endpoint">
4249
<span class="method get">GET</span>
4350
<strong>/api/v1/services/{namespace}/{name}</strong>
44-
<p>Get details for a specific service</p>
45-
<p><strong>Example:</strong> <code>/api/v1/services/production/my-service</code></p>
51+
<p>Get details for a specific workload</p>
4652
</div>
4753
4854
<div class="endpoint">
@@ -54,7 +60,7 @@ func getHTMLPage() string {
5460
<div class="endpoint">
5561
<span class="method get">GET</span>
5662
<strong>/api/v1/namespaces</strong>
57-
<p>List all namespaces with service counts</p>
63+
<p>List all namespaces with workload counts</p>
5864
</div>
5965
6066
<div class="endpoint">
@@ -63,14 +69,21 @@ func getHTMLPage() string {
6369
<p>Get OpenAPI specification</p>
6470
</div>
6571
72+
<div class="endpoint">
73+
<span class="method get">GET</span>
74+
<strong>/metrics</strong>
75+
<p>Prometheus metrics (workload health gauges, HTTP request counters, Go runtime)</p>
76+
</div>
77+
6678
<h2>Resources</h2>
6779
<ul>
6880
<li><a href="/api/v1/spec">OpenAPI Specification</a></li>
81+
<li><a href="/metrics">Prometheus Metrics</a></li>
6982
<li><a href="/health">Health Check</a></li>
7083
<li><a href="/ready">Readiness Check</a></li>
7184
</ul>
7285
73-
<p><em>For full documentation see <code>/api/v1/spec</code></em></p>
86+
<p><em>For agent integration see <code>docs/SKILL.md</code> in the repository</em></p>
7487
</body>
7588
</html>`
7689
}

internal/server/openapi.go

Lines changed: 47 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ func getOpenAPISpec(r *http.Request) map[string]interface{} {
1212
"openapi": "3.0.0",
1313
"info": map[string]interface{}{
1414
"title": "DeployScope API",
15-
"description": "RESTful API for monitoring Kubernetes deployment statuses",
15+
"description": "RESTful API for monitoring Kubernetes workload statuses (Deployments, StatefulSets, DaemonSets)",
1616
"version": APIVersion,
1717
},
1818
"servers": []map[string]interface{}{
@@ -21,8 +21,8 @@ func getOpenAPISpec(r *http.Request) map[string]interface{} {
2121
"paths": map[string]interface{}{
2222
"/services": map[string]interface{}{
2323
"get": map[string]interface{}{
24-
"summary": "List all services",
25-
"description": "List all services with pagination, filtering, and sorting",
24+
"summary": "List all workloads",
25+
"description": "List all workloads with pagination, filtering, and sorting",
2626
"parameters": []map[string]interface{}{
2727
{
2828
"name": "page", "in": "query",
@@ -54,6 +54,11 @@ func getOpenAPISpec(r *http.Request) map[string]interface{} {
5454
"description": "Filter by version",
5555
"schema": map[string]string{"type": "string"},
5656
},
57+
{
58+
"name": "type", "in": "query",
59+
"description": "Filter by workload type",
60+
"schema": map[string]interface{}{"type": "string", "enum": []string{"deployment", "statefulset", "daemonset"}},
61+
},
5762
{
5863
"name": "sort", "in": "query",
5964
"description": "Sort field (name, namespace, version, status, replicas). Prefix '-' for desc",
@@ -74,30 +79,30 @@ func getOpenAPISpec(r *http.Request) map[string]interface{} {
7479
},
7580
"/services/{namespace}/{name}": map[string]interface{}{
7681
"get": map[string]interface{}{
77-
"summary": "Get service by ID",
78-
"description": "Get details for a specific service",
82+
"summary": "Get workload by ID",
83+
"description": "Get details for a specific workload",
7984
"parameters": []map[string]interface{}{
8085
{
8186
"name": "namespace", "in": "path", "required": true,
82-
"description": "Service namespace",
87+
"description": "Workload namespace",
8388
"schema": map[string]string{"type": "string"},
8489
},
8590
{
8691
"name": "name", "in": "path", "required": true,
87-
"description": "Service name",
92+
"description": "Workload name",
8893
"schema": map[string]string{"type": "string"},
8994
},
9095
},
9196
"responses": map[string]interface{}{
9297
"200": map[string]interface{}{"description": "Successful response"},
93-
"404": map[string]interface{}{"description": "Service not found"},
98+
"404": map[string]interface{}{"description": "Workload not found"},
9499
},
95100
},
96101
},
97102
"/summary": map[string]interface{}{
98103
"get": map[string]interface{}{
99104
"summary": "Get summary statistics",
100-
"description": "Get aggregate statistics for all services",
105+
"description": "Get aggregate statistics for all workloads",
101106
"responses": map[string]interface{}{
102107
"200": map[string]interface{}{"description": "Successful response"},
103108
},
@@ -106,7 +111,7 @@ func getOpenAPISpec(r *http.Request) map[string]interface{} {
106111
"/namespaces": map[string]interface{}{
107112
"get": map[string]interface{}{
108113
"summary": "List all namespaces",
109-
"description": "List all namespaces with service counts",
114+
"description": "List all namespaces with workload counts",
110115
"responses": map[string]interface{}{
111116
"200": map[string]interface{}{"description": "Successful response"},
112117
},
@@ -118,16 +123,38 @@ func getOpenAPISpec(r *http.Request) map[string]interface{} {
118123
"ServiceStatus": map[string]interface{}{
119124
"type": "object",
120125
"properties": map[string]interface{}{
121-
"id": map[string]string{"type": "string", "example": "production/my-service"},
122-
"name": map[string]string{"type": "string"},
123-
"namespace": map[string]string{"type": "string"},
124-
"version": map[string]string{"type": "string"},
125-
"image": map[string]string{"type": "string"},
126-
"replicas": map[string]string{"type": "integer"},
127-
"ready_replicas": map[string]string{"type": "integer"},
128-
"status": map[string]interface{}{"type": "string", "enum": []string{"green", "yellow", "red"}},
129-
"created_at": map[string]string{"type": "string", "format": "date-time"},
130-
"updated_at": map[string]string{"type": "string", "format": "date-time"},
126+
"id": map[string]string{"type": "string", "example": "production/my-service"},
127+
"name": map[string]string{"type": "string"},
128+
"namespace": map[string]string{"type": "string"},
129+
"workload_type": map[string]interface{}{"type": "string", "enum": []string{"deployment", "statefulset", "daemonset"}},
130+
"version": map[string]string{"type": "string"},
131+
"image": map[string]string{"type": "string"},
132+
"replicas": map[string]string{"type": "integer"},
133+
"ready_replicas": map[string]string{"type": "integer"},
134+
"status": map[string]interface{}{"type": "string", "enum": []string{"green", "yellow", "red"}},
135+
"owner": map[string]interface{}{"type": "string", "nullable": true, "description": "From deployscope.dev/owner annotation"},
136+
"tier": map[string]interface{}{"type": "string", "nullable": true, "description": "From deployscope.dev/tier annotation (critical, standard, best-effort)"},
137+
"managed_by": map[string]interface{}{"type": "string", "nullable": true, "description": "From app.kubernetes.io/managed-by label"},
138+
"part_of": map[string]interface{}{"type": "string", "nullable": true, "description": "From app.kubernetes.io/part-of label"},
139+
"depends_on": map[string]interface{}{"type": "array", "items": map[string]string{"type": "string"}, "description": "From deployscope.dev/depends-on annotation"},
140+
"integration": map[string]string{"$ref": "#/components/schemas/Integration"},
141+
"last_transition": map[string]interface{}{"type": "string", "format": "date-time", "nullable": true, "description": "Most recent K8s condition transition"},
142+
"created_at": map[string]string{"type": "string", "format": "date-time"},
143+
"updated_at": map[string]string{"type": "string", "format": "date-time"},
144+
},
145+
},
146+
"Integration": map[string]interface{}{
147+
"type": "object",
148+
"description": "Integration pointers from deployscope.dev/* annotations",
149+
"properties": map[string]interface{}{
150+
"gitops_repo": map[string]interface{}{"type": "string", "nullable": true},
151+
"gitops_path": map[string]interface{}{"type": "string", "nullable": true},
152+
"oncall": map[string]interface{}{"type": "string", "nullable": true},
153+
"runbook": map[string]interface{}{"type": "string", "nullable": true},
154+
"dashboard": map[string]interface{}{"type": "string", "nullable": true},
155+
"health_endpoint": map[string]interface{}{"type": "string", "nullable": true},
156+
"deep_health": map[string]interface{}{"type": "string", "nullable": true},
157+
"deep_health_detail": map[string]interface{}{"type": "string", "nullable": true},
131158
},
132159
},
133160
"PaginatedResponse": map[string]interface{}{

0 commit comments

Comments
 (0)