NAME
IO::K8s::APIObject - Base class for top-level Kubernetes API objects
VERSION
version 1.110
SYNOPSIS
# Built-in API object (api_version/kind derived from class name):
package IO::K8s::Api::Core::V1::Pod;
use IO::K8s::APIObject;
k8s spec => 'Core::V1::PodSpec';
k8s status => 'Core::V1::PodStatus';
1;
# Custom Resource Definition (CRD):
package My::StaticWebSite;
use IO::K8s::APIObject
api_version => 'homelab.example.com/v1',
resource_plural => 'staticwebsites';
with 'IO::K8s::Role::Namespaced';
k8s spec => Opaque;
k8s status => Opaque;
1;
DESCRIPTION
Like IO::K8s::Resource, but for top-level Kubernetes API objects. Automatically applies IO::K8s::Role::APIObject which provides:
metadataattributeapi_version()method (derived from class name)kind()method (derived from class name)resource_plural()method (from a generated table for built-in Kinds;undefwhen there is no plural, e.g. a subresource)Label, annotation, condition, and owner convenience methods
api_version() and resource_plural() are fixed identity methods, not writable fields: when a CRD declares its own via the import parameters below, passing an argument croaks rather than silently rebinding. The methods derive their value from the class name in the built-in case, so the same guard applies -- see IO::K8s::Role::APIObject for the exact messages.
For Custom Resource Definitions (CRDs), pass api_version and optionally resource_plural as import parameters. These are installed as class methods before the role is composed, avoiding redefinition warnings.
api_version, resource_plural and subresources (below) are the only import parameters. Any other name -- a typo such as subresource or resource_plurals -- croaks at the use line before anything is set up, naming the class, the parameter and the known ones:
My::StaticWebSite: unknown import parameter 'subresource' for IO::K8s::APIObject (known: api_version, resource_plural, subresources)
The same goes for an odd number of import arguments, and for an api_version or resource_plural given as undef, as an empty string or as a reference, which used to be skipped as if the parameter were not there:
My::StaticWebSite: odd number of import arguments for IO::K8s::APIObject (1); expected name => value pairs
My::StaticWebSite: import parameter 'resource_plural' for IO::K8s::APIObject must be a non-empty string, got an empty string
A CRD class may also declare the subresources its CRD version serves, which "to_crd" in IO::K8s::Role::APIObject writes into spec.versions[].subresources:
package My::StaticWebSite;
use IO::K8s::APIObject
api_version => 'homelab.example.com/v1',
resource_plural => 'staticwebsites',
subresources => {
status => {},
scale => {
specReplicasPath => '.spec.replicas',
statusReplicasPath => '.status.replicas',
labelSelectorPath => '.status.selector'
}
};
subresources becomes a fixed identity class method like api_version: it returns a fresh copy of the declaration on every call, and passing an argument croaks (subresources is fixed for this class and cannot be set). A class without the parameter has no subresources method, and its to_crd writes no subresources key. The declaration is checked at use time: only status and scale are known; status is an empty hashref; scale needs specReplicasPath and statusReplicasPath, takes labelSelectorPath as well, and nothing else, each a non-empty string. An empty hashref declares no subresource. Anything else croaks naming the class and the key, for example
My::StaticWebSite: unknown subresource 'foo' (known: scale, status)
My::StaticWebSite: subresource 'scale' needs 'statusReplicasPath'
A class "add_crd" in IO::K8s generates from a CRD version with subresources gets the same method, and IO::K8s::CRD::Emitter renders it as this parameter.
Every class built this way gets IO::K8s::Role::SpecBuilder for deep-path spec manipulation (spec_get, spec_set, spec_array, spec_hash, spec_push, spec_merge, spec_delete), walking a typed spec through its own declared fields as readily as a plain hash one -- built-in Kinds as well as CRDs, since 1.108. A Kind that carries no spec field at all (ConfigMap, Secret, the RBAC kinds, ...) has the methods too, and every one of them croaks naming the class rather than failing on a missing accessor.
Use IO::K8s::Resource for embedded objects (PodSpec, Container, etc.) and IO::K8s::APIObject for top-level resources (Pod, Deployment, Service, etc.)
SUPPORT
Issues
Please report bugs and feature requests on GitHub at https://github.com/pplu/io-k8s-p5/issues.
CONTRIBUTING
Contributions are welcome! Please fork the repository and submit a pull request.
AUTHORS
Torsten Raudssus <getty@cpan.org>
Jose Luis Martinez Torres <jlmartin@cpan.org>
COPYRIGHT AND LICENSE
This software is Copyright (c) 2018-2026 by Jose Luis Martinez Torres <jlmartin@cpan.org>.
This is free software, licensed under:
The Apache License, Version 2.0, January 2004