NAME
IO::K8s::Role::CertManaged - Role for cert-manager certificate and issuer management
VERSION
version 1.108
SYNOPSIS
package My::Certificate;
use IO::K8s::APIObject
api_version => 'cert-manager.io/v1',
resource_plural => 'certificates';
with 'IO::K8s::Role::CertManaged';
package main;
my $k8s = IO::K8s->new(with => ['IO::K8s::CertManager']);
my $cert = $k8s->new_object('Certificate',
metadata => { name => 'example', namespace => 'default' },
);
$cert->for_domains('example.com', '*.example.com')
->with_issuer('letsencrypt-prod', kind => 'ClusterIssuer')
->store_in_secret('example-tls');
DESCRIPTION
This role provides the fluent certificate and issuer builders documented in the README's cert-manager section. Methods on the top half (for_domains, with_issuer, store_in_secret, add_ip_san, renew_before) operate on Certificate CRDs; methods on the bottom half (letsencrypt, self_signed, ca, add_http01_solver, add_dns01_solver) operate on Issuer / ClusterIssuer CRDs. They are defined on the same role because the underlying spec shape overlaps and the consumer's CRD classes typically declare both.
The two halves can be composed on the same class or split across two -- the role does not enforce separation. Each setter returns $self, so the chain reads top-to-bottom in declaration order regardless of which half each call belongs to.
Validation is performed up-front: add_ip_san croaks on a non-IP value, letsencrypt croaks if email is missing, and ca croaks if secret is missing. Croak rather than silent skip -- the consumer should not ship a manifest that the cluster will reject.
for_domains
$cert->for_domains(@domains);
Adds @domains to the certificate's spec.dnsNames array. Existing entries are preserved; duplicates are not deduplicated. This is the caller-facing way to populate the SAN list for a Certificate CRD -- the common name (CN) is taken from the first entry by cert-manager. Returns $self for chaining.
$cert->for_domains('example.com', '*.example.com');
with_issuer
$cert->with_issuer($name, kind => 'Issuer', group => 'cert-manager.io');
Sets spec.issuerRef to point at the named issuer. kind defaults to Issuer and group to cert-manager.io; pass kind => 'ClusterIssuer' for cluster-scoped issuers. Returns $self for chaining.
$cert->with_issuer('letsencrypt-prod', kind => 'ClusterIssuer');
store_in_secret
$cert->store_in_secret($secret_name);
Sets spec.secretName to the Kubernetes Secret name cert-manager should write the issued certificate into. Returns $self for chaining.
$cert->store_in_secret('example-tls');
add_ip_san
$cert->add_ip_san(@ips);
Adds @ips to the certificate's spec.ipAddresses array after validating each one through "IPAddress" in IO::K8s::Types::Net. Croaks if any value is not a valid IPv4 or IPv6 address. Duplicates are not deduplicated. Returns $self for chaining.
$cert->add_ip_san('10.0.0.1', '192.168.1.1');
renew_before
$cert->renew_before(days => $n);
$cert->renew_before(hours => $n);
Sets spec.renewBefore from either days or hours. The value is formatted as a Go duration string "<nh0m0s"> -- the wire format cert-manager accepts. Pass exactly one of the two keys; if both are given days wins. Returns $self for chaining.
letsencrypt
$issuer->letsencrypt(email => $addr, production => 1, secret => 'le-account');
Configures spec.acme to obtain certificates from Let's Encrypt. The email option is mandatory and croaks if missing; production => 1 selects the production ACME directory and 0 (the default) selects the staging directory. secret names the Secret that holds the ACME account private key (defaults to letsencrypt-account-key). Returns $self for chaining.
$issuer->letsencrypt(email => 'ops@example.com', production => 1);
self_signed
$issuer->self_signed;
Configures spec.selfSigned as an empty hash -- cert-manager's signal that the issuer issues certificates from itself. This is the issuer-side counterpart of the self-signed CA bootstrapping flow. Returns $self for chaining.
ca
$issuer->ca(secret => 'my-ca-key');
Configures spec.ca with the Secret name holding the CA private key and certificate. secret is required and croaks if missing. Returns $self for chaining.
$issuer->ca(secret => 'internal-ca');
add_http01_solver
$issuer->add_http01_solver(class => 'nginx');
Appends an HTTP-01 challenge solver to spec.acme.solvers. The solver configures cert-manager to satisfy ACME challenges via an Ingress; pass class => $name to write that exact ingress.class value. Without class, this method emits an empty ingress block and does not choose an Ingress class. Returns $self for chaining.
$issuer->add_http01_solver(class => 'nginx');
add_dns01_solver
$issuer->add_dns01_solver(provider => 'cloudflare', secret => 'cf-token', key => 'api-token');
$issuer->add_dns01_solver(provider => 'route53', region => 'us-east-1');
$issuer->add_dns01_solver(provider => 'acme-dns');
Appends a DNS-01 challenge solver to spec.acme.solvers. The provider option selects the underlying solver block -- cloudflare and route53 get the matching cloud-specific shape; any other provider name is written as a bare { provider => {} } block, leaving the details for the consumer to fill in. secret / key are Cloudflare-specific (the Kubernetes Secret holding the API token and the key inside that Secret, defaulting to api-token); region is Route53-specific. Returns $self for chaining.
SEE ALSO
IO::K8s::CertManager, IO::K8s::Types::Net, IO::K8s::APIObject
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