feat: Add support for server-side content negotiation#7531
feat: Add support for server-side content negotiation#7531ash-thakur-rh wants to merge 6 commits intofabric8io:mainfrom
Conversation
| server.expect().get() | ||
| .withPath("/api/v1/namespaces/default/pods/my-pod") | ||
| .andReturn(200, podPartialMetadata("my-pod", "default", "app", "backend", "version", "v1")) | ||
| .once(); |
There was a problem hiding this comment.
AS discussed internally.
The HTTP mock should return different objects depending on the header provided. IF the header matches the one for partial metadata, the server should respond only with metadata fields, if not it should return everything.
(You can create this with a proper function in the expectation that checks the headers -I think-)
There was a problem hiding this comment.
If you switch to use KubeApiTest, you won't even need to mock the response and we can be sure that the Kube API behaves as expected
| assertThat(result.getMetadata().getLabels()) | ||
| .containsEntry("app", "backend") | ||
| .containsEntry("version", "v1"); |
There was a problem hiding this comment.
Once the previous comment is implemented, we should actually have an assertion to check that the other fields in the Pod are empty (spec, status)
1375e21 to
2264601
Compare
2264601 to
f1c128a
Compare
There was a problem hiding this comment.
The test is good, but I'm not sure this is the right place.
Ideally this should be in a different module. Tests here are supposed to be testing kubeapitest functionality and not kubernetes client implementations.
|
The last commit you created is plainly wrong. It removed the Kube API tests and used mocks instead. That's not ok. |

Description
Adds support for two Kubernetes server-side content negotiation formats via the Accept header, allowing clients to receive lightweight or display-optimized representations of resources without changing the API endpoint. Both
features work across all resource types: built-in resources, CRDs, and custom resources.
Fixes #7451
Fixes #5716
PartialObjectMetadata
Fetches only the metadata of a resource (no spec, no status). The server strips the heavy fields before sending, significantly reducing payload size. Useful in controllers and operators that need to watch or list many resources but only care about labels, annotations, UIDs, or resource versions.
Accept header:
application/json;as=PartialObjectMetadata;g=meta.k8s.io;v=v1New model classes (kubernetes-model-core):
PartialObjectMetadata: implements HasMetadata, contains apiVersion, kind, metadataPartialObjectMetadataList: extends DefaultKubernetesResourceList<PartialObjectMetadata>New DSL interfaces (kubernetes-client-api):
MetadataGettable: getAsPartialObjectMetadata() → returns null on 404, consistent with get()MetadataListable: listAsPartialObjectMetadata() and listAsPartialObjectMetadata(ListOptions)Wired into:
Resource<T>extends MetadataGettableFilterWatchListDeletable<T,L,R>extends MetadataListableTable
Fetches a server-rendered table: the same format used by kubectl get. The server returns columnDefinitions (headers) and rows (one per resource), with each row's cells aligned by index with columnDefinitions. Column names and count are decided by the server based on resource type; priority == 0 columns are the default view, priority > 0 are wide columns (kubectl get -o wide).
Accept header:
application/json;as=Table;v=v1;g=meta.k8s.ioNew model classes (kubernetes-model-core):
Table: columnDefinitions, rows, metadata (ListMeta); annotated with @JsonIgnoreProperties(ignoreUnknown = true) to tolerate server-side field additionsTableColumnDefinition: name, type, format, description, priorityTableRow(cells): List<Object>, optional object: RawExtension; annotated with @JsonIgnoreProperties(ignoreUnknown = true) to handle conditions and other optional server fieldsNew DSL interfaces (kubernetes-client-api):
TableGettable: getAsTable() → returns null on 404TableListable: listAsTable() and listAsTable(ListOptions)Wired into:
Resource<T>extends TableGettableFilterWatchListDeletable<T,L,R>extends TableListableShared Implementation Details
BaseOperationimplements all four methods with the appropriate Accept headersgetAsPartialObjectMetadata()andgetAsTable()both catch HTTP 404 and return null, matching the behaviour ofget()ResourceAdapterdelegatesgetAsPartialObjectMetadata()andgetAsTable()to the wrapped resourceinNamespace(),inAnyNamespace(),withLabel(),withField(),withName(), andListOptions(pagination, label/field selectors)Type of change
test, version modification, documentation, etc.)
Checklist