https://github.com/pplu/io-k8s-p5
Objects representing things found in the Kubernetes API
https://github.com/pplu/io-k8s-p5
kubernetes kubernetes-api perl
Last synced: about 2 months ago
JSON representation
Objects representing things found in the Kubernetes API
- Host: GitHub
- URL: https://github.com/pplu/io-k8s-p5
- Owner: pplu
- Created: 2018-05-03T22:53:46.000Z (about 8 years ago)
- Default Branch: master
- Last Pushed: 2026-03-19T21:30:27.000Z (3 months ago)
- Last Synced: 2026-03-20T11:52:04.123Z (3 months ago)
- Topics: kubernetes, kubernetes-api, perl
- Language: Perl
- Homepage:
- Size: 2.18 MB
- Stars: 1
- Watchers: 2
- Forks: 3
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- Changelog: Changes
Awesome Lists containing this project
README
# IO::K8s
Perl objects representing the Kubernetes API (v1.31).
## Description
This module provides Perl objects and serialization/deserialization methods that represent the structures found in the Kubernetes API (v1.31).
Kubernetes API is strict about input types. When a value is expected to be an integer, sending it as a string will cause rejection. This module ensures correct value types in JSON that can be sent to Kubernetes.
It also inflates JSON returned by Kubernetes into typed Perl objects.
## Installation
From CPAN:
```bash
cpanm IO::K8s
```
From source:
```bash
cpanm --installdeps .
dzil build
dzil test
dzil install
```
## Usage
```perl
use IO::K8s;
my $k8s = IO::K8s->new;
# Create objects with short names
my $pod = $k8s->new_object('Pod',
metadata => { name => 'my-pod', namespace => 'default' },
spec => { containers => [{ name => 'app', image => 'nginx' }] }
);
# Load and validate YAML manifests
my $resources = $k8s->load_yaml('deployment.yaml');
# Save to YAML file
$pod->save('pod.yaml');
# Inflate JSON/struct into typed objects (auto-detect class from 'kind')
my $svc = $k8s->json_to_object('Service', '{"kind":"Service"}');
my $obj = $k8s->inflate({ kind => 'Pod', metadata => { name => 'test' } });
# Serialize back to JSON
my $json = $k8s->object_to_json($svc);
my $struct = $k8s->object_to_struct($pod);
```
## Bundled CRD Providers
IO::K8s ships with CRD classes for popular Kubernetes ecosystem projects. None are loaded by default - opt in at construction:
```perl
my $k8s = IO::K8s->new(with => [
'IO::K8s::Cilium',
'IO::K8s::Traefik',
'IO::K8s::CertManager',
'IO::K8s::K3s',
'IO::K8s::GatewayAPI',
'IO::K8s::AgentSandbox',
]);
```
### Cilium (21 CRDs)
`IO::K8s::Cilium` covers `cilium.io/v2` and `cilium.io/v2alpha1` (upstream v1.19.2):
```perl
my $k8s = IO::K8s->new(with => ['IO::K8s::Cilium']);
my $cnp = $k8s->new_object('CiliumNetworkPolicy',
metadata => { name => 'allow-dns', namespace => 'kube-system' },
spec => { endpointSelector => {} },
);
```
### Traefik (10 CRDs)
`IO::K8s::Traefik` covers `traefik.io/v1alpha1`:
```perl
my $k8s = IO::K8s->new(with => ['IO::K8s::Traefik']);
my $ir = $k8s->new_object('IngressRoute',
metadata => { name => 'my-route', namespace => 'default' },
spec => { entryPoints => ['web'], routes => [{ match => 'Host(`example.com`)' }] },
);
```
### cert-manager (6 CRDs)
`IO::K8s::CertManager` covers `cert-manager.io/v1` and `acme.cert-manager.io/v1`:
```perl
my $k8s = IO::K8s->new(with => ['IO::K8s::CertManager']);
my $cert = $k8s->new_object('Certificate',
metadata => { name => 'my-cert', namespace => 'default' },
spec => { secretName => 'my-cert-tls', issuerRef => { name => 'letsencrypt' } },
);
```
### K3s (4 CRDs)
`IO::K8s::K3s` covers `helm.cattle.io/v1` and `k3s.cattle.io/v1` (upstream v1.35.1+k3s1):
```perl
my $k8s = IO::K8s->new(with => ['IO::K8s::K3s']);
my $hc = $k8s->new_object('HelmChart',
metadata => { name => 'traefik', namespace => 'kube-system' },
spec => { chart => 'traefik' },
);
```
### Gateway API (5 CRDs)
`IO::K8s::GatewayAPI` covers `gateway.networking.k8s.io/v1` and `gateway.networking.k8s.io/v1beta1`:
```perl
my $k8s = IO::K8s->new(with => ['IO::K8s::GatewayAPI']);
my $gw = $k8s->new_object('Gateway',
metadata => { name => 'my-gateway', namespace => 'default' },
spec => { gatewayClassName => 'istio', listeners => [{ name => 'http', port => 80 }] },
);
```
### AgentSandbox (4 CRDs)
`IO::K8s::AgentSandbox` covers `agents.x-k8s.io/v1alpha1` and `extensions.agents.x-k8s.io/v1alpha1` (upstream v0.2.1):
```perl
my $k8s = IO::K8s->new(with => ['IO::K8s::AgentSandbox']);
my $sandbox = $k8s->new_object('Sandbox',
metadata => { name => 'my-sandbox', namespace => 'default' },
spec => { replicas => 1, shutdownPolicy => 'Retain' },
);
```
## Convenience Roles
All API objects automatically get label, annotation, condition, and owner reference methods:
```perl
# Labels & annotations (all API objects)
$pod->add_label(app => 'web');
$pod->add_labels(app => 'web', tier => 'frontend');
$pod->has_label('app'); # true
$pod->match_labels(app => 'web'); # true
$pod->add_annotation('prometheus.io/scrape' => 'true');
# Status conditions (objects with status)
$deploy->is_ready;
$deploy->is_condition_true('Available');
$deploy->condition_message('Progressing');
# Owner references
$pod->set_owner($deployment);
$pod->is_owned_by($deployment);
```
CRD classes automatically get deep-path spec manipulation via `SpecBuilder`:
```perl
$ir->spec_set('tls.secretName', 'my-cert');
$ir->spec_get('routes.0.match');
$ir->spec_push('routes', { match => 'Host(`api.example.com`)' });
$ir->spec_merge(entryPoints => ['web', 'websecure']);
$ir->spec_delete('tls');
```
Domain-specific builder roles provide fluent APIs for common tasks:
```perl
# Network policies (core K8s + Cilium)
$netpol->select_pods(app => 'web')
->allow_ingress_from_pods({ app => 'nginx' }, ports => [{ port => 8080 }])
->allow_egress_to_dns
->deny_all_egress;
# HTTP routing (Ingress, HTTPRoute, IngressRoute)
$route->add_hostname('example.com')
->add_backend('api-v1', port => 8080, weight => 90)
->add_path_match('/api', type => 'Prefix');
# cert-manager
$cert->for_domains('example.com', '*.example.com')
->with_issuer('letsencrypt-prod', kind => 'ClusterIssuer')
->store_in_secret('example-tls');
# K3s Helm charts
$chart->from_repo('https://traefik.github.io/charts', 'traefik')
->set_version('25.0.0')
->set_values(replicas => 3);
# Traefik middleware
$mw->rate_limit(average => 100, burst => 200)
->strip_prefix('/api')
->redirect_https;
```
### IP Type Validation
`IO::K8s::Types::Net` provides Net::IP-backed type constraints:
```perl
use IO::K8s::Types::Net qw( IPv4 IPv6 IPAddress CIDR NetIP );
use IO::K8s::Types::Net qw( parse_ip cidr_contains is_rfc1918 );
cidr_contains('10.0.0.0/8', '10.1.2.3'); # true
is_rfc1918('192.168.1.1'); # true
```
## External Resource Maps
Merge resource maps from external packages (e.g. `IO::K8s::Cilium` or your own CRD packages):
```perl
# At construction time
my $k8s = IO::K8s->new(with => ['IO::K8s::Cilium']);
# Or at runtime
$k8s->add('IO::K8s::Cilium');
# Disambiguate colliding kind names with domain-qualified strings
$k8s->new_object('cilium.io/v2/CiliumNetworkPolicy', { ... });
# Or with api_version parameter
$k8s->new_object('CiliumNetworkPolicy', { ... }, 'cilium.io/v2');
# inflate() auto-uses apiVersion from JSON data
$k8s->inflate('{"kind":"CiliumNetworkPolicy","apiVersion":"cilium.io/v2",...}');
```
### pk8s DSL
In `.pk8s` manifest files, Cilium kinds work directly:
```perl
CiliumNetworkPolicy {
name => 'allow-dns',
namespace => 'kube-system',
spec => { endpointSelector => {} },
};
CiliumNode {
name => 'worker-1',
spec => { addresses => [{ type => 'InternalIP', ip => '10.0.0.1' }] },
};
```
## Custom Resource Definitions (CRDs)
Write your own CRD classes using `IO::K8s::APIObject`:
```perl
package My::StaticWebSite;
use IO::K8s::APIObject
api_version => 'homelab.example.com/v1',
resource_plural => 'staticwebsites';
with 'IO::K8s::Role::Namespaced';
k8s spec => { Str => 1 };
k8s status => { Str => 1 };
1;
```
Or generate them dynamically from an OpenAPI schema using `IO::K8s::AutoGen`.
See the full POD documentation for details on the class architecture and CRD support.
## Features
- Support for Kubernetes v1.31 API objects
- Type-safe object creation and serialization
- Lightweight Moo-based implementation
- Handles all Kubernetes resource types (Pods, Services, Deployments, etc.)
- Custom Resource Definition (CRD) support with `IO::K8s::APIObject` import parameters
- External resource map support with collision handling (`add()`, `with` constructor param)
- Domain-qualified resource names for disambiguation (`api_version/Kind`)
- Dynamic class generation from OpenAPI schemas via `IO::K8s::AutoGen`
- Convenience methods: labels, annotations, conditions, owner references on all API objects
- Deep-path spec manipulation for CRD classes via `SpecBuilder`
- Domain-specific builder roles for network policies, routing, certificates, Helm, and more
- Net::IP-backed IP/CIDR type constraints (`IO::K8s::Types::Net`)
- Proper handling of namespaced resources
- Canonical JSON output for consistent API requests
## Links
- CPAN: https://metacpan.org/pod/IO::K8s
- GitHub: https://github.com/pplu/io-k8s-p5
- Issues: https://github.com/pplu/io-k8s-p5/issues
- Kubernetes API Reference: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.31/
## Authors
- Torsten Raudssus
- Jose Luis Martinez (original author, inactive)
## License
Copyright (c) 2018 by Jose Luis Martinez
This code is distributed under the Apache 2 License. The full text of the license can be found in the LICENSE file included with this module.
## Support
- IRC: #kubernetes on irc.perl.org
- Issues: https://github.com/pplu/io-k8s-p5/issues
## See Also
- [Kubernetes::REST](https://metacpan.org/pod/Kubernetes::REST) - Kubernetes REST API client
- [IO::K8s::Resource](https://metacpan.org/pod/IO::K8s::Resource) - Base class for all Kubernetes resources