Revision history for Kubernetes-REST

1.106     2026-08-08 19:03:58Z

 - Fix "HTTP::Message content must be bytes" on any request body containing
   a non-ASCII character. The internal JSON encoder now uses utf8 => 1 (plus
   canonical and convert_blessed), so request bodies leave as UTF-8 bytes.
   Applying manifests with e.g. a section sign or an en dash in a
   description -- the upstream cert-manager CRDs, among others -- died
   before ever reaching the cluster.
 - Fix silent mojibake on non-ASCII response values under the default LWP
   backend. LWPIO used decoded_content(), handing back characters that
   IO::K8s then decoded a second time; it now uses
   decoded_content(charset => 'none'), matching HTTPTinyIO. Both backends
   now inflate identical objects from identical bytes, which t/24_encoding.t
   pins.
 - Response bodies and streaming chunks are bytes across every IO backend --
   documented in Kubernetes::REST::Role::IO as the encoding contract that
   custom backends must honour, and in a new ENCODING section in
   Kubernetes::REST. Objects handed to and returned by the API carry
   characters; log() output stays bytes, as container output is not
   guaranteed to be text.
 - API error messages are now UTF-8 decoded before being croaked, so a
   non-ASCII error body from the cluster is readable instead of garbled.
 - The CLI's JSON output encoder now sets utf8, so non-ASCII values print
   as correct UTF-8 instead of triggering "Wide character in print".
 - Require IO::K8s 1.105 (was 1.008). IO::K8s has decoded with utf8 => 1
   since 1.000, so the encoding fix above works on the old minimum too --
   the bump just tracks the current release.
 - Move the five packages that shared a file with another package into files
   of their own: Kubernetes::REST::RemoteError (was in Error.pm) and the
   four Kubernetes::REST::CLI::Cmd::* command classes (were in CLI.pm). All
   five reported $VERSION 1.003, the version they were written in, because
   RewriteVersion and BumpVersionAfterRelease only ever rewrite the first
   "our $VERSION" per file -- while the metadata reported the release
   version, so 1.105 shipped a CLI::Cmd::Get saying 1.003 in the code and
   1.105 in META. One package per file removes the whole class of problem;
   t/25_one_package_per_file.t keeps it removed.
 - Kubernetes::REST::RemoteError has to be loaded explicitly now. Loading
   Kubernetes::REST::Error no longer brings it along -- RemoteError inherits
   from it, so the parent file has to finish loading first, which a circular
   use cannot do. Code catching these deprecated exceptions is unaffected;
   code throwing one needs "use Kubernetes::REST::RemoteError".
 - Give bin/kube_client and bin/kube_watch a $VERSION of their own; they
   were the only files in the distribution without one.

1.105     2026-08-08 02:34:04Z

 - Remove the old v0 API's per-endpoint Call::* classes (1002) and 10
   v0-only helper modules (CallContext, Apis, Logs, Extensions,
   Result2Hash, ListToRequest, Result2Object, Settings, Version,
   Auditregistration). Since the 1.000 v1 rewrite these only ever emitted a
   deprecation warning on load and had no other function; nothing in this
   distribution referenced them anymore. Their old module names are now
   tombstoned in Kubernetes-REST-Deprecated so PAUSE doesn't keep
   resolving them to this dist's stale 1.104 release.
 - Note: the Kubernetes::REST::V0Group family ($api->Core, $api->Apps,
   etc.) is NOT affected -- it's a still-functional AUTOLOAD-based
   compatibility layer, not a dead stub, and continues to ship as before.

1.104     2026-04-14 16:41:31Z
 - Add ensure(), ensure_all(), ensure_only() for idempotent create-or-update.
   Handles 404/409 race conditions and server-side immutability for
   PersistentVolumeClaim and Job. Accepts either typed IO::K8s objects or
   plain hashrefs (inflated via struct_to_object).

1.103     2026-03-25 20:09:12Z
 - Add Claude Code skills (.claude/skills/) for kubernetes-rest API reference,
   @Author::GETTY bundle, and dist.ini analysis
 - Add .gitignore rules for .claude/ directory (track skills, ignore session data)
 - Fix CPAN testers: replace ->@* postfix dereference with @{ } in t/08_crd.t
   and t/09_crd_autogen.t for Perl < 5.24 compatibility

1.102     2026-03-09 08:36:25Z
 - Pod Exec API: new `exec()` method in active v1 API.
   Builds `/exec` requests, supports repeated `command=` parameters and stream
   toggles (stdin/stdout/stderr/tty), and passes duplex callbacks
   (on_open/on_frame/on_close/on_error) to IO backends.
 - Pod Attach API: new `attach()` method in active v1 API.
   Builds `/attach` requests with stream toggles
   (stdin/stdout/stderr/tty) and passes duplex callbacks
   (on_open/on_frame/on_close/on_error) to IO backends.

1.101     2026-03-08 23:49:18Z
 - Raise minimum required IO::K8s version to 1.008.
   Needed for CRD YAML serialization correctness with JSON booleans in
   passthrough/hash fields (fix in IO::K8s 1.008).
 - Pod Port-Forward API: new port_forward() method in active v1 API.
   Builds /portforward requests, supports multiple ports, and passes duplex
   callbacks (on_open/on_frame/on_close/on_error) to IO backends.
 - _prepare_request now supports array query parameters (repeated key=value)
   and explicit header overrides/additions.
 - Kubernetes::REST::Role::IO adds supports_duplex() capability probe and
   documents optional call_duplex() transport hook.

1.100     2026-03-04 16:41:39Z
 - Pod Log API: new log() method for retrieving and streaming pod logs.
   Supports one-shot (returns full log text) and streaming mode (on_line
   callback with Kubernetes::REST::LogEvent objects). Streaming mode supports
   follow, tailLines, sinceSeconds, sinceTime, timestamps, previous,
   limitBytes, and container parameters.
 - New Kubernetes::REST::LogEvent class for typed log line events
 - Public building block methods for async wrappers: build_path(),
   prepare_request(), check_response(), inflate_object(), inflate_list(),
   process_watch_chunk(), process_log_chunk(). These provide a stable public
   API for event-based systems like Net::Async::Kubernetes to integrate
   without relying on internal methods.

1.004     2026-02-28 18:46:30Z
 - Fix resource name pluralization in _build_path: correctly handle words ending
   in ss/sh/ch/x/z (e.g. Ingress -> ingresses, NetworkPolicy -> networkpolicies),
   consonant+y (e.g. Policy -> policies), and avoid double-s for words already
   ending in s.

1.003     2026-02-28 01:05:55Z
 - Kubernetes::REST::Kubeconfig: add in-cluster service account auto-detection.
   When no kubeconfig file is found, automatically falls back to using the
   mounted service account token at
   /var/run/secrets/kubernetes.io/serviceaccount/token. This enables seamless
   use inside Kubernetes pods without needing a kubeconfig file.

1.002     2026-02-23 02:41:32Z
 - Fix client-certificate (mTLS) auth: skip empty Authorization header when
   no bearer token is configured (was sending "Bearer " causing 401)

1.001     2026-02-20 05:03:44Z
 - Fix inline kubeconfig certificates (use IO::Socket::SSL::Utils for in-memory PEM)
 - Kubeconfig: respect KUBECONFIG environment variable

1.000     2026-02-13 05:38:17Z
 - Updated original author email and copyright holder
 - Complete rewrite for v1 API
 - Now uses IO::K8s for Kubernetes resource classes
 - Simplified API: list(), get(), create(), update(), patch(), delete(), watch()
 - Default HTTP backend switched from HTTP::Tiny to LWP::UserAgent
   (enables LWP::ConsoleLogger for HTTP traffic debugging)
 - New Kubernetes::REST::LWPIO backend (HTTPTinyIO still available as alternative)
 - Pluggable IO architecture via Kubernetes::REST::Role::IO
 - Patch support: strategic-merge-patch, JSON merge patch (RFC 7396),
   JSON patch (RFC 6902)
 - Watch API: streaming resource changes via Kubernetes Watch API
 - Resumable watches via resourceVersion tracking
 - Label and field selector support for list() and watch()
 - Automatic URL building from IO::K8s class metadata
 - Custom Resource Definition (CRD) support with the standard API
 - Resource map for short class names (Pod -> IO::K8s::Api::Core::V1::Pod)
 - Resource map '+' prefix for external classes ('+My::CRD' uses class as-is)
 - Dynamic resource map loading from cluster (/openapi/v2)
 - Kubeconfig support (token auth, client certs, exec credential plugins)
 - New kube_watch CLI tool for watching Kubernetes resource events
 - Backwards compatibility via deprecated v0 API wrappers (with warnings)
 - Updated maintainer to GETTY

All pre-v1 releases by Jose Luis Martinez Torres (JLMARTIN)

0.02     2019-02-11 00:00:00Z
 - Fix all calls that have a body parameter: Create*, Patch*, Replace*, etc..

0.01     2019-01-03 00:00:00Z
 - First release into an unsuspecting world
