Revision history for IO-K8s

1.105     2026-08-08 18:51:44Z

  - Removed the 76 individual *List classes (PodList, ServiceList,
    DeploymentList, etc.) that have emitted "use IO::K8s::List instead"
    deprecation warnings since the 1.00 Moose-to-Moo rewrite. They were
    never real classes in the 1.x series and this release drops them from
    the distribution entirely. Code that still references one of these
    names (e.g. via cpanfile or `use`) will now fail to install instead of
    silently warning; install IO::K8s::Deprecated for a clear redirect
    message pointing at IO::K8s::List. This also removes four namespaces
    that held nothing but a List stub and are now gone entirely --
    IO::K8s::ApiExtensionsApiServer, IO::K8s::Api::Auditregistration,
    IO::K8s::Api::Extensions, IO::K8s::Api::Settings -- plus several
    now-empty single-version subdirectories under Apps, Autoscaling, Batch,
    Certificates, Coordination, Events, KubeAggregator, Policy, Rbac, and
    Scheduling. Full old-name list: IO::K8s::Deprecated's POD.
  - Restored the 8 Cilium v2alpha1/v2 classes dropped in 1.100's Cilium
    v1.19.2 upgrade (CiliumBGPAdvertisement, CiliumBGPClusterConfig,
    CiliumBGPNodeConfig, CiliumBGPNodeConfigOverride, CiliumBGPPeerConfig,
    CiliumCIDRGroup under Cilium::V2alpha1; CiliumBGPPeeringPolicy under
    Cilium::V2alpha1; CiliumExternalWorkload under Cilium::V2). These now
    ship alongside their current-API-version siblings for backward
    compatibility with clusters still running older Cilium releases,
    matching this dist's existing convention of keeping multiple API
    versions of a resource side by side (e.g. Apps V1beta1/V1beta2/V1).
  - Synced all API surfaces to their current upstream releases (previous
    target: Kubernetes v1.31 and CRD providers pinned months/years back).
    Kubernetes core moved v1.31 -> v1.36; CRD providers moved
    Cilium v1.19.2 -> v1.20.0, K3s v1.35.1+k3s1 -> v1.36.3+k3s1,
    Traefik v3.0.0 -> v3.7.10 (CRD set unchanged across v3.x),
    cert-manager v1.19.3 -> v1.21.1 (no CRD/field changes),
    Gateway API v1.1.0 -> v1.6.1, Agent Sandbox v0.2.1 -> v0.5.4.
    * Cilium: added CiliumDatapathPlugin (cilium.io/v2alpha1, new in
      v1.20.0's Extensible Datapath feature).
    * Gateway API: added BackendTLSPolicy, ListenerSet, TLSRoute,
      TCPRoute, UDPRoute (all gateway.networking.k8s.io/v1), and a
      gateway.networking.k8s.io/v1 ReferenceGrant alongside the existing
      v1beta1 (still the short-name/storage version); TLSRoute joins
      HTTPRoute/GRPCRoute in consuming IO::K8s::Role::Routable.
    * Agent Sandbox: all four CRDs gained a v1beta1 track (now the
      storage version) with real schema changes -- Sandbox drops
      spec/status.replicas for spec.operatingMode + spec.service +
      status.nodeName/podIPs; SandboxClaim drops spec.sandboxTemplateRef
      for a required spec.warmPoolRef and gains
      spec.additionalPodMetadata, spec.env, spec.lifecycle,
      a typed spec.volumeClaimTemplates list, and
      status.sandbox.name (was status.sandbox.Name); SandboxTemplate
      gains spec.envVarsInjectionPolicy, spec.service,
      spec.volumeClaimTemplates, spec.volumeClaimTemplatesPolicy;
      SandboxWarmPool gains spec.updateStrategy.type. v1alpha1 survives
      as served-but-deprecated on all four.
    * K3s and cert-manager: version bump only, no CRD/field-level changes
      upstream.
    * Traefik: version bump only; CRD set confirmed unchanged across the
      whole v3.x line.
    * Core Kubernetes -- workloads: added container restart rules
      (Container/EphemeralContainer restartPolicyRules), pod-level
      resources (PodSpec.resources, PodStatus.allocatedResources/
      resources), PodSpec.hostnameOverride and .schedulingGroup (gang
      scheduling), PodStatus.observedGeneration and DRA-related extended
      resource claim status fields, HorizontalPodAutoscaler per-direction
      scaling tolerance, DeploymentStatus/ReplicaSetStatus
      .terminatingReplicas, NodeStatus.declaredFeatures.
    * Core Kubernetes -- networking: added networking.k8s.io/v1
      ServiceCIDR and IPAddress (stable since v1.33; deprecated v1beta1
      kept alongside), made NetworkPolicySpec.podSelector optional
      (upstream now defaults it), added discovery.k8s.io/v1 EndpointHints
      .forNodes / ForNode for PreferSameNode topology routing.
    * Core Kubernetes -- security/admission: added
      MutatingAdmissionPolicy/MutatingAdmissionPolicyBinding (GA in v1),
      PodCertificateRequest (certificates.k8s.io/v1beta1), and
      ClusterTrustBundle at v1beta1 alongside the existing v1alpha1.
      The older v1alpha1/v1beta1 ValidatingAdmissionPolicy and
      authentication.k8s.io/{v1alpha1,v1beta1} SelfSubjectReview tracks,
      and flowcontrol.apiserver.k8s.io/v1beta3, were evaluated for
      removal (no longer served by a v1.36 apiserver) but kept in this
      release rather than deleted, matching this dist's Cilium-precedent
      of preferring backward compatibility over deletion for classes that
      already shipped in a prior CPAN release -- deleting a
      previously-released module name without a tombstone would orphan
      it on PAUSE. Left as a maintainer decision for a future release.
    * Core Kubernetes -- storage/DRA: added resource.k8s.io/v1 (GA)
      Dynamic Resource Allocation -- DeviceClass, ResourceClaim,
      ResourceClaimTemplate, ResourceSlice and their full nested type
      graph -- replacing the old v1alpha3-only control-plane-controller
      allocation mode (DRA graduated to GA in Kubernetes v1.34).
      Also added resource.k8s.io/v1beta2 DeviceTaintRule,
      resource.k8s.io/v1alpha3 ResourcePoolStatusRequest,
      scheduling.k8s.io/v1alpha2 PodGroup/Workload (gang scheduling),
      storage.k8s.io/v1 VolumeAttributesClass (GA),
      coordination.k8s.io/v1beta1 LeaseCandidate, and new CSIDriverSpec
      fields (nodeAllocatableUpdatePeriodSeconds,
      preventPodSchedulingIfMissing, serviceAccountTokenInSecrets).
      Fixed a pre-existing bug found while verifying the new DRA classes:
      the api_version group map in IO::K8s::Role::APIObject was missing
      an entry for "resource", so every Api::Resource::* class (both the
      pre-existing v1alpha3 ones and the new ones added here) rendered
      apiVersion as "resource/vX" instead of the correct
      "resource.k8s.io/vX" -- would have produced manifests rejected by
      any real cluster. Fixed by adding resource => 'resource.k8s.io' to
      the map.
      Removed four resource.k8s.io/v1alpha3 classes --
      PodSchedulingContext, PodSchedulingContextSpec,
      PodSchedulingContextStatus, ResourceClaimSchedulingStatus --
      confirmed removed from the live v1.36 API (the "classic DRA"
      control-plane-controller allocation flow they supported was fully
      superseded by the new v1 structured-parameters model). Unlike the
      admission/auth/flowcontrol classes noted above, these had no
      lingering old-cluster back-compat rationale to keep them (DRA
      itself was alpha-only when these shipped, never GA, so there is no
      "still-supported old cluster" using them the way there is for a
      long-GA API's deprecated beta track) -- maintainer confirmed
      removal. Since these names already shipped in IO-K8s 1.100, PAUSE
      redirect tombstones for all four were added to the companion
      IO::K8s::Deprecated distribution rather than left to silently
      orphan.

1.100     2026-03-25 19:17:28Z
  - Added IO::K8s::AgentSandbox with 4 CRD classes for agent-sandbox (v0.2.1):
    Sandbox (agents.x-k8s.io/v1alpha1), SandboxClaim, SandboxTemplate,
    SandboxWarmPool (extensions.agents.x-k8s.io/v1alpha1)
  - Added inline struct support to k8s DSL: hash specs with multiple keys now
    auto-generate typed inner classes with hashref coercion, supporting nested
    structs and proper TO_JSON serialization
  - Upgraded IO::K8s::Cilium from ~v1.17 to v1.19.2: promoted 6 BGP CRDs and
    CiliumCIDRGroup from v2alpha1 to v2, removed CiliumExternalWorkload and
    CiliumBGPPeeringPolicy, fixed scope on CiliumEgressGatewayPolicy and
    CiliumGatewayClassConfig (23 → 21 CRDs)
  - Upgraded IO::K8s::K3s to v1.35.1+k3s1: added ETCDSnapshotFile
    (cluster-scoped, k3s.cattle.io/v1) (3 → 4 CRDs)
  - Added upstream_version() method to all CRD providers for tracking which
    upstream release each provider is based on

1.010     2026-03-24 13:17:59Z
  - Added missing Test::Deep test dependency (CPAN Testers failure)

1.009     2026-03-19 21:29:24Z
  - Fix: coerce \0/\1 refs to plain 0/1 for Bool attributes — Perl's \0 is a
    truthy reference, so users passing \0 expecting JSON false got wrong results.
    Bool attributes now dereference scalar refs before coercing.
  - Updated dist.ini authors and copyright holder

1.008     2026-03-08 23:36:05Z
  - Fix to_yaml handling for JSON booleans in resource hashes — TO_YAML now uses
    YAML::PP with JSON schema and JSON::PP boolean mode, so JSON::PP::true/false
    serialize as true/false instead of 1/0 or refs.
  - Added test for CRD to_yaml with JSON booleans in passthrough spec hash.

1.007     2026-03-08 15:01:36Z
  - Fix import leak: using an IO::K8s class (e.g. use IO::K8s::Api::Core::V1::Secret)
    no longer contaminates the caller's namespace with the k8s DSL function or
    IO::K8s::Role::Resource. Previously, _setup_class used extends (inheritance),
    causing every IO::K8s subclass to inherit Resource's import method and re-run
    _setup_class on any package that loaded it. Now uses Moo::Role composition
    (apply_roles_to_package) instead, so the import method stays in IO::K8s::Resource.
  - IO::K8s::Resource no longer composes IO::K8s::Role::Resource itself (it is
    NOT a resource, it is the DSL/setup class).
  - _k8s_attr_info is now called as a method on the target class (via the composed
    Role::Resource) instead of as a direct function call on IO::K8s::Resource.
  - Added regression test t/27_no_import_leak.t.

1.006     2026-03-01 02:55:20Z
  - Fix struct_to_object destroying pre-built objects: when a typed IO::K8s
    object was passed into a parent constructor (e.g. PersistentVolumeClaim in
    StatefulSet.volumeClaimTemplates), _inflate_struct treated the blessed
    object as a non-HASH ref and returned {}, producing an empty object.
    Now passes through objects that already match the expected class.
  - Harden _inflate_struct against blessed objects: if a blessed object
    reaches _inflate_struct despite the struct_to_object guard, it now
    extracts data via TO_JSON instead of silently returning {}.
  - Add explicit Scalar::Util import to IO::K8s (was used unimported).
  - Added comprehensive test suite: passthrough tests (t/23), combination
    tests with 35 subtests (t/24), real-world YAML manifest round-trip tests
    from popular projects like Kubernetes Dashboard, CoreDNS, Prometheus,
    Argo CD, NGINX Ingress, Grafana (t/25), and build-and-verify tests
    constructing manifests via Perl API and checking output (t/26).
    Total: 1047 assertions across 29 test files.

1.005     2026-02-28 06:43:29Z
  - Fixed _inflate_struct not recognizing sanitized field names (x-kubernetes-*,
    $ref, etc.) during JSON deserialization — Bool coercion and type inflation
    were skipped for these fields, causing JSON::PP::Boolean type constraint
    failures on e.g. x-kubernetes-preserve-unknown-fields

1.004     2026-02-28 05:42:53Z
  - Fixed JSONSchemaProps compilation: field names with special characters
    ($ref, $schema, x-kubernetes-*) are now automatically sanitized to valid
    Perl identifiers (e.g. _ref, _schema, x_kubernetes_embedded_resource)
    with init_arg mapping so constructors still accept the original JSON keys
  - Added comprehensive compile test (t/02_compile_all.t) loading all 697 modules

1.003     2026-02-28 00:35:50Z

1.002     2026-02-23 02:37:32Z
  - Added Authorization API types to default resource map
    (SelfSubjectRulesReview, SelfSubjectAccessReview, SubjectAccessReview,
    LocalSubjectAccessReview)
  - Added Authentication API types to default resource map
    (TokenReview, TokenRequest, SelfSubjectReview)

1.001     2026-02-14 19:07:12Z
  - Added IO::K8s::Types::Net with Net::IP-backed IP/CIDR type constraints
  - Added convenience methods to IO::K8s::Role::APIObject: labels, annotations,
    status conditions, and owner references for all API objects
  - Added IO::K8s::Role::SpecBuilder for deep-path spec manipulation on CRD classes
  - Added IO::K8s::Role::NetworkPolicy for building network policies (core K8s + Cilium)
  - Added IO::K8s::Role::Routable for HTTP/gRPC routing (Ingress, HTTPRoute, IngressRoute)
  - Added IO::K8s::Role::CertManaged for cert-manager Certificate/Issuer building
  - Added IO::K8s::Role::HelmManaged for K3s HelmChart/HelmChartConfig building
  - Added IO::K8s::Role::Loadbalanced for TraefikService traffic distribution
  - Added IO::K8s::Role::MiddlewareBuilder for Traefik middleware configuration
  - SpecBuilder is auto-applied to all CRD classes via IO::K8s::APIObject import
  - Added Net::IP as dependency
  - Added IO::K8s::Traefik with 10 Traefik CRD classes (traefik.io/v1alpha1)
  - Added IO::K8s::K3s with 3 K3s CRD classes (helm.cattle.io/v1 and k3s.cattle.io/v1)
  - Added IO::K8s::CertManager with 6 cert-manager CRD classes (cert-manager.io/v1 and acme.cert-manager.io/v1)
  - Added IO::K8s::GatewayAPI with 5 Gateway API CRD classes (gateway.networking.k8s.io/v1 and v1beta1)
  - Added IO::K8s::Cilium with 23 Cilium CRD classes (cilium.io/v2 and cilium.io/v2alpha1)
  - Added IO::K8s::Role::ResourceMap for external resource map providers
  - Added add() method to merge external resource maps (e.g. CRD packages)
  - Added 'with' constructor parameter for merging resource maps at construction
  - Added domain-qualified resource names (api_version/Kind) for collision handling
  - expand_class(), new_object(), inflate() now support api_version disambiguation
  - pk8s DSL functions accept optional api_version second argument
  - resource_map default now returns a copy per instance (safe for mutation)
  - Updated original author email and copyright holder

1.000     2026-02-13 01:52:24Z
  - Major refactoring: Migrated from Moose to Moo for lighter dependencies
  - Replaced YAML::XS with YAML::PP for pure Perl implementation
  - Updated to Kubernetes v1.31 API objects
  - New IO::K8s::List class for unified list handling
  - Improved attribute metadata handling with IO::K8s::Resource
  - Added IO::K8s::APIObject and IO::K8s::Role::APIObject for better API object support
  - Added support for namespaced resources via IO::K8s::Role::Namespaced
  - Added resource_plural support to IO::K8s::Role::APIObject for CRD classes
  - IO::K8s::APIObject accepts import parameters (api_version, resource_plural) for CRDs
  - IO::K8s::AutoGen supports CRD metadata (api_version, kind, resource_plural, is_namespaced)
  - expand_class recognizes already-loaded classes (needed for CRD classes)
  - Improved JSON serialization with canonical output
  - Better handling of opaque fields (fieldsV1, rawExtension, raw)
  - Deprecation stubs for removed List classes (backwards compatibility)
  - Added IO::K8s::Types for Type::Tiny type library integration

0.04     2018-12-11 00:00:00Z
  - Update to Kubernetes v1.14 API objects

0.03     2018-05-15 00:00:00Z
  - add convenience to_json method to all objects (meis)
  - add Test::Exception as dependency (manwar)

0.02     2018-05-08 00:00:00Z
  - Kubernetes API sometimes returns key => undef. We handle this not initializing the attribute to undef,
    since it's functionally the same to initialize it to undef or not initialize it

0.01     2018-05-04 00:00:00Z
  - Initial release to an unsuspecting world
