-
Notifications
You must be signed in to change notification settings - Fork 2
auto-docs: Update Cloud API spec #71
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2729,6 +2729,16 @@ components: | |
| created: | ||
| $ref: '#/components/schemas/Created' | ||
| type: object | ||
| NetworkUpdate: | ||
| description: Resource describing an Update Network. | ||
| properties: | ||
| id: | ||
| description: ID of the network. | ||
| type: string | ||
| required: | ||
| - id | ||
| title: NetworkUpdate | ||
| type: object | ||
| NullValue: | ||
| description: |- | ||
| `NullValue` is a singleton enumeration to represent the null value for the | ||
|
|
@@ -2759,6 +2769,7 @@ components: | |
| - TYPE_DELETE_SERVERLESS_PRIVATE_LINK | ||
| - TYPE_CREATE_NETWORK_PEERING | ||
| - TYPE_DELETE_NETWORK_PEERING | ||
| - TYPE_UPDATE_NETWORK | ||
| - TYPE_CREATE_SHADOW_LINK | ||
| - TYPE_UPDATE_SHADOW_LINK | ||
| - TYPE_DELETE_SHADOW_LINK | ||
|
|
@@ -4342,6 +4353,16 @@ components: | |
| group: | ||
| $ref: '#/components/schemas/Group' | ||
| type: object | ||
| UpdateNetworkMetadata: | ||
| description: Resource describing an in-progress UpdateNetwork Operation. | ||
| title: UpdateNetworkMetadata | ||
| type: object | ||
| UpdateNetworkOperation: | ||
| description: UpdateNetworkOperation is the response of the update network rpc. | ||
| properties: | ||
| operation: | ||
| $ref: '#/components/schemas/v1.Operation' | ||
| type: object | ||
| UpdateOrganizationResponse: | ||
| properties: | ||
| organization: | ||
|
|
@@ -6332,6 +6353,60 @@ paths: | |
| summary: Get network | ||
| tags: | ||
| - Networks | ||
| /v1/networks/{network.id}: | ||
| patch: | ||
| description: Update a Redpanda network. | ||
| operationId: NetworkService_UpdateNetwork | ||
| parameters: | ||
| - description: ID of the network. | ||
| in: path | ||
| name: network.id | ||
| required: true | ||
| schema: | ||
| type: string | ||
|
Comment on lines
+6356
to
+6366
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
python - <<'PY'
import re
from collections import defaultdict
from pathlib import Path
text = Path("cloud-controlplane/cloud-controlplane.yaml").read_text()
in_paths = False
paths = []
for line in text.splitlines():
if line.strip() == "paths:":
in_paths = True
continue
if in_paths and re.match(r'^\S', line):
break
m = re.match(r'^ (/[^:]+):\s*$', line)
if in_paths and m:
paths.append(m.group(1))
normalized = defaultdict(list)
for path in paths:
normalized[re.sub(r'\{[^}]+\}', '{}', path)].append(path)
for key, variants in sorted(normalized.items()):
if len(variants) > 1:
print(key)
for variant in variants:
print(f" - {variant}")
PYRepository: redpanda-data/api-docs Length of output: 522 🏁 Script executed: #!/bin/bash
set -euo pipefail
FILE="cloud-controlplane/cloud-controlplane.yaml"
echo "=== Find /v1/networks/{id} path block ==="
rg -n --fixed-string ' /v1/networks/{id}:' "$FILE" -n || true
python - <<'PY'
from pathlib import Path
import re
p=Path("cloud-controlplane/cloud-controlplane.yaml")
lines=p.read_text().splitlines()
# find indices for the two path keys
targets=[" /v1/networks/{id}:"," /v1/networks/{network.id}:"]
for t in targets:
idx=[i for i,l in enumerate(lines) if l.strip()==t.strip()]
print(t, "count", len(idx), "indices", idx[:5])
if idx:
i=idx[0]
# print from a bit before to a bit after
start=max(0,i-5); end=min(len(lines), i+60)
print("\n--- Context for", t, "lines", start+1, "-", end, "---")
for k in range(start,end):
print(f"{k+1:>6} {lines[k]}")
PY
echo "=== Find all operations directly under those two path keys (method lines) ==="
python - <<'PY'
from pathlib import Path
import re
FILE=Path("cloud-controlplane/cloud-controlplane.yaml")
lines=FILE.read_text().splitlines()
def collect_methods(path_key):
methods=[]
# find line with exact key
idx=None
for i,l in enumerate(lines):
if l.strip()==path_key.strip():
idx=i
break
if idx is None:
return methods
# scan until next top-level path key (2 spaces indent, starts with /)
for j in range(idx+1,len(lines)):
l=lines[j]
if re.match(r'^ /[^:]+:\s*$', l.strip()):
break
m=re.match(r'^\s{4}([a-z]+):\s*$', l) # 4 spaces then http method
if m:
methods.append(m.group(1))
return methods
print("methods for /v1/networks/{id}:", collect_methods(" /v1/networks/{id}:"))
print("methods for /v1/networks/{network.id}:", collect_methods(" /v1/networks/{network.id}:"))
PYRepository: redpanda-data/api-docs Length of output: 6784 🌐 Web query:
💡 Result: In the OpenAPI 3 specification, paths that share the same hierarchy but use different parameter names in their templates (such as /users/{id} and /users/{network.id}) are considered identical and are strictly invalid [1][2][3]. The OpenAPI Specification explicitly states: "Templated paths with the same hierarchy but different templated names MUST NOT exist as they are identical" [1][3]. Because OpenAPI tooling normalizes these templates by treating the placeholder (the text inside the braces) as a generic segment, both {id} and {network.id} are effectively reduced to the same internal signature (e.g., /users/{}). Validator behavior typically includes the following: 1. Invalid Specification: Most linters and schema validators will flag this as an error because the structure is ambiguous and violates the specification's uniqueness requirements [4]. 2. Tooling Failure: Code generators and diffing tools often fail when they encounter these paths because they cannot distinguish between the two templates, leading to errors like "Two path items have the same signature" [4]. 3. Ambiguous Routing: If a validator fails to catch this, actual API routing becomes ambiguous. Since the specification considers them identical, there is no standardized behavior for how an API server or client should resolve which path to use, and it is left to the individual implementation [1][2]. To resolve this issue, you must use consistent parameter names across identical path structures or restructure your API to ensure the paths themselves are distinct (e.g., /users/{id} vs /networks/{network.id}/users/{id}) [5][4]. Citations:
🌐 Web query:
💡 Result: In OpenAPI, dots '.' are allowed in the path parameter name (the identifier inside { }), as the spec does not restrict the parameter-name characters to exclude '.'. [1] What OpenAPI does restrict is the content/value of a path parameter: the path parameter value MUST NOT contain any unescaped “generic syntax” characters described by RFC3986: forward slashes (/), question marks (?), or hashes (#). This restriction is about the parameter value at runtime, not the name/identifier inside the curly braces. [2][3] So {user.name} as a template name is permitted by the OpenAPI rules, but the actual value substituted for {user.name} cannot include unescaped '/', '?', or '#'. [1][2] Citations:
Merge
/v1/networks/{network.id}:
patch:
description: Update a Redpanda network.
operationId: NetworkService_UpdateNetwork
parameters:
- description: ID of the network.
in: path
name: network.id
required: true
schema:
type: string🤖 Prompt for AI Agents |
||
| requestBody: | ||
| content: | ||
| application/json: | ||
| schema: | ||
| description: Resource describing an Update Network. | ||
| required: | ||
| - network | ||
| title: NetworkUpdate | ||
| type: object | ||
| description: |- | ||
| NetworkUpdate | ||
|
|
||
| Resource describing an Update Network. | ||
| required: true | ||
|
Comment on lines
+6367
to
+6380
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Define the PATCH payload instead of requiring an undeclared field. The request schema marks 🤖 Prompt for AI Agents |
||
| x-originalParamName: network | ||
| responses: | ||
| "202": | ||
| content: | ||
| application/json: | ||
| schema: | ||
| $ref: '#/components/schemas/UpdateNetworkOperation' | ||
| description: Accepted | ||
| "404": | ||
| content: | ||
| application/json: | ||
| schema: | ||
| $ref: '#/components/schemas/rpc.Status' | ||
| description: Not Found | ||
| "500": | ||
| content: | ||
| application/json: | ||
| schema: | ||
| $ref: '#/components/schemas/rpc.Status' | ||
| description: Internal Server Error. Please reach out to support. | ||
| default: | ||
| content: | ||
| application/json: | ||
| schema: | ||
| $ref: '#/components/schemas/rpc.Status' | ||
| description: An unexpected error response. | ||
| summary: Update network | ||
| tags: | ||
| - Networks | ||
| /v1/operations: | ||
| get: | ||
| description: List operations. This is a generic endpoint and can be used to list any type of operation. | ||
|
|
@@ -6356,6 +6431,7 @@ paths: | |
| - TYPE_DELETE_SERVERLESS_PRIVATE_LINK | ||
| - TYPE_CREATE_NETWORK_PEERING | ||
| - TYPE_DELETE_NETWORK_PEERING | ||
| - TYPE_UPDATE_NETWORK | ||
| - TYPE_CREATE_SHADOW_LINK | ||
| - TYPE_UPDATE_SHADOW_LINK | ||
| - TYPE_DELETE_SHADOW_LINK | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wire update-network into the generic operation unions.
UpdateNetworkMetadataandUpdateNetworkOperationare added here, butv1.Operationstill cannot represent aTYPE_UPDATE_NETWORKoperation in the generic operations endpoints becauseOperationMetadatalacks theUpdateNetworkMetadatabranch andOperationResponsehas noUpdateNetworkResponsebranch at all.Minimal wiring to add
OperationMetadata: oneOf: + - allOf: + - properties: + '`@type`': + description: Fully qualified protobuf type name of the underlying response, prefixed with `type.googleapis.com/`. + enum: + - type.googleapis.com/redpanda.api.controlplane.v1.UpdateNetworkMetadata + type: string + - $ref: '`#/components/schemas/UpdateNetworkMetadata`' + UpdateNetworkResponse: + properties: + network: + $ref: '`#/components/schemas/Network`' + type: object + OperationResponse: oneOf: + - allOf: + - properties: + '`@type`': + description: Fully qualified protobuf type name of the underlying response, prefixed with `type.googleapis.com/`. + enum: + - type.googleapis.com/redpanda.api.controlplane.v1.UpdateNetworkResponse + type: string + - $ref: '`#/components/schemas/UpdateNetworkResponse`'🤖 Prompt for AI Agents