diff --git a/changelogs/fragments/20251027-metadata-only-fetches.yaml b/changelogs/fragments/20251027-metadata-only-fetches.yaml new file mode 100644 index 0000000000..4fac2cfd03 --- /dev/null +++ b/changelogs/fragments/20251027-metadata-only-fetches.yaml @@ -0,0 +1,2 @@ +minor_changes: + - k8s_info - Support for metadata-only fetches in k8s_info module (https://github.com/ansible-collections/kubernetes.core/pull/1030) diff --git a/docs/kubernetes.core.k8s_info_module.rst b/docs/kubernetes.core.k8s_info_module.rst index cbd56febd3..d55617aedf 100644 --- a/docs/kubernetes.core.k8s_info_module.rst +++ b/docs/kubernetes.core.k8s_info_module.rst @@ -280,6 +280,29 @@ Parameters
List of label selectors to use to filter results
+ + +
+ metadata_only + +
+ boolean +
+
added in 6.3.0
+ + + + + +
Request metadata only response from the Kubernetes API server.
+
This feature is useful for clients that only need to check for the existence of an object,
+
or that only need to read its metadata.
+
It can significantly reduce the size of the response from the API server.
+ +
@@ -701,6 +724,12 @@ Examples wait_sleep: 10 wait_timeout: 360 + - name: Get a list of all pods metadata only + kubernetes.core.k8s_info: + kind: Pod + metadata_only: true + register: pod_metadata_list + Return Values diff --git a/plugins/module_utils/args_common.py b/plugins/module_utils/args_common.py index 0ea022c52c..60b87badaf 100644 --- a/plugins/module_utils/args_common.py +++ b/plugins/module_utils/args_common.py @@ -144,3 +144,18 @@ def _extract_recursive(data, current_path=""): "options": {"resourceVersion": {"type": "str"}, "uid": {"type": "str"}}, }, } + +METADATA_ONLY_HEADERS_SPEC = dict( + accept=dict(type="str"), +) + +METADATA_ONLY_HEADER_VALUES = { + "partial_object": ( + "application/json;as=PartialObjectMetadata;g=meta.k8s.io;v=v1," + "application/json;q=0.9" + ), + "partial_object_list": ( + "application/json;as=PartialObjectMetadataList;g=meta.k8s.io;v=v1," + "application/json;q=0.9" + ), +} diff --git a/plugins/module_utils/k8s/client.py b/plugins/module_utils/k8s/client.py index 197c34b967..2ab2eed651 100644 --- a/plugins/module_utils/k8s/client.py +++ b/plugins/module_utils/k8s/client.py @@ -181,6 +181,7 @@ def _create_headers(module=None, **kwargs): header_map = { "impersonate_user": "Impersonate-User", "impersonate_groups": "Impersonate-Group", + "accept": "Accept", } headers = {} diff --git a/plugins/modules/k8s_info.py b/plugins/modules/k8s_info.py index 306425ad01..d2c5bbe016 100644 --- a/plugins/modules/k8s_info.py +++ b/plugins/modules/k8s_info.py @@ -53,6 +53,15 @@ type: list elements: str version_added: 3.0.0 + metadata_only: + description: + - Request metadata only response from the Kubernetes API server. + - This feature is useful for clients that only need to check for the existence of an object, + - or that only need to read its metadata. + - It can significantly reduce the size of the response from the API server. + type: bool + default: false + version_added: 6.3.0 extends_documentation_fragment: - kubernetes.core.k8s_auth_options @@ -120,6 +129,12 @@ namespace: default wait_sleep: 10 wait_timeout: 360 + +- name: Get a list of all pods metadata only + kubernetes.core.k8s_info: + kind: Pod + metadata_only: true + register: pod_metadata_list """ RETURN = r""" @@ -164,6 +179,8 @@ ) from ansible_collections.kubernetes.core.plugins.module_utils.args_common import ( AUTH_ARG_SPEC, + METADATA_ONLY_HEADERS_SPEC, + METADATA_ONLY_HEADER_VALUES, WAIT_ARG_SPEC, ) from ansible_collections.kubernetes.core.plugins.module_utils.k8s.client import ( @@ -209,6 +226,7 @@ def argspec(): label_selectors=dict(type="list", elements="str", default=[]), field_selectors=dict(type="list", elements="str", default=[]), hidden_fields=dict(type="list", elements="str"), + metadata_only=dict(type="bool", default=False), ) ) return args @@ -218,8 +236,20 @@ def main(): module = AnsibleK8SModule( module_class=AnsibleModule, argument_spec=argspec(), supports_check_mode=True ) + + metadata_only_headers = {} + if module.params["metadata_only"]: + metadata_only_headers = copy.deepcopy(METADATA_ONLY_HEADERS_SPEC) + metadata_only_headers.update( + dict(accept=METADATA_ONLY_HEADER_VALUES["partial_object_list"]) + ) + if module.params["name"]: + metadata_only_headers.update( + dict(accept=METADATA_ONLY_HEADER_VALUES["partial_object"]) + ) + try: - client = get_api_client(module) + client = get_api_client(module, **metadata_only_headers) svc = K8sService(client, module) execute_module(module, svc) except CoreException as e: diff --git a/tests/integration/targets/k8s_info/tasks/main.yml b/tests/integration/targets/k8s_info/tasks/main.yml index 7235564033..3b58e89ff3 100644 --- a/tests/integration/targets/k8s_info/tasks/main.yml +++ b/tests/integration/targets/k8s_info/tasks/main.yml @@ -4,3 +4,4 @@ - wait - api-server-caching - discovery + - metadata-only-fetches diff --git a/tests/integration/targets/k8s_info/tasks/metadata-only-fetches.yml b/tests/integration/targets/k8s_info/tasks/metadata-only-fetches.yml new file mode 100644 index 0000000000..57791c3900 --- /dev/null +++ b/tests/integration/targets/k8s_info/tasks/metadata-only-fetches.yml @@ -0,0 +1,22 @@ +--- +- name: Retrieve Node list with metadata_only + kubernetes.core.k8s_info: + kind: Node + metadata_only: true + register: node_metadata_only_list + +- name: Assert response has kind PartialObjectMetadata + assert: + that: + - node_metadata_only_list.resources[0].kind == "PartialObjectMetadata" + +- name: Retrieve full Node list + kubernetes.core.k8s_info: + kind: Node + metadata_only: false + register: node_full_list + +- name: Assert response has kind Node + assert: + that: + - node_full_list.resources[0].kind == "Node"