Documentation
¶
Index ¶
- Constants
- type APIServiceProxy
- type CertRenewer
- type IssueClientCertResponse
- type Option
- func WithAPIHost(host string) Option
- func WithCertDir(dir string) Option
- func WithClusterName(name string) Option
- func WithKubeconfigPath(path string) Option
- func WithLocalMode(local bool) Option
- func WithNamespace(ns string) Option
- func WithProjectID(id string) Option
- func WithRenewInterval(d time.Duration) Option
- func WithRenewThreshold(d time.Duration) Option
- func WithServiceName(name string) Option
- func WithToken(token string) Option
- type Options
Constants ¶
const ( // DefaultCertDir is the in-pod mount path of the apiz-cert Secret. // The apoxy-cloud onboarding manifest must mount the Secret at this // path for hot-reload to engage. If the mount is absent the watcher // no-ops and falls back to the legacy restart-driven rotation. DefaultCertDir = "/etc/apoxy/certs" // Apoxy API headers. ApoxyAPIKeyHeaderKey = "x-apoxy-api-key" ApoxyProjectIdHeaderKey = "x-apoxy-project-id" ApoxyServiceUserKey = "x-apoxy-service-user" )
const ( // CertExpiryMetricName is the gauge the CLI scrapes from a running // pod to confirm `apoxy k8s certs rotate --no-restart` took effect. // Exported so the rotate-flow caller doesn't hard-code the string. CertExpiryMetricName = "apoxy_kube_controller_cert_expiry_seconds" // CertRenewalsMetricName is the auto-renewal outcome counter (vector // with a `result` label). Exported so integration tests and alert // rules can reference the canonical name. CertRenewalsMetricName = "apoxy_kube_controller_cert_renewals_total" // Event reasons emitted by the auto-renewer on the kube-controller // Deployment. Exported so tests and docs can match the canonical // strings rather than copying literals. EventReasonCertRenewed = "CertRenewed" EventReasonCertRenewalFailed = "CertRenewalFailed" )
const ( DefaultRenewInterval = time.Hour DefaultRenewThreshold = 30 * 24 * time.Hour )
Default cadence + threshold for cert auto-renewal. The renewer attempts renewal once per RenewInterval, and only when the live cert's remaining validity drops below RenewThreshold. With cosmos's 365-day certs that means each pod self-renews ~once a year, well before expiry.
const (
DefaultPort = 8443
)
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type APIServiceProxy ¶
type APIServiceProxy struct {
// contains filtered or unexported fields
}
APIServiceProxy is a proxy for the Apoxy API.
func NewAPIServiceProxy ¶
func NewAPIServiceProxy( ctx context.Context, kC kubernetes.Interface, opts ...Option, ) (*APIServiceProxy, error)
NewAPIServiceProxy creates a new APIServiceProxy with the given options.
func (*APIServiceProxy) CABundle ¶
func (p *APIServiceProxy) CABundle() []byte
CABundle returns the CA bundle for the APIServiceProxy.
type CertRenewer ¶
type CertRenewer struct {
// contains filtered or unexported fields
}
CertRenewer auto-renews the upstream client cert by re-calling cosmos's IssueServiceCert endpoint over mTLS with the current live cert. The renewer writes the new Secret; the fsnotify watcher (reload.Watch) then picks up the new files and swaps the live transport in place.
CertRenewer implements sigs.k8s.io/controller-runtime/pkg/manager.Runnable so it can be added to a leader-elected manager. Wrapping the loop in a manager Runnable means a future multi-replica kube-controller will issue against cosmos from one pod per tick, not all of them.
func NewCertRenewer ¶
func NewCertRenewer( apiSvc *APIServiceProxy, recorder record.EventRecorder, deployRef *corev1.ObjectReference, ) *CertRenewer
NewCertRenewer wires a renewer onto an already-configured APIServiceProxy. The proxy must have been constructed via NewAPIServiceProxy with cloud options (project ID + token) so its certStore is seeded.
recorder may be nil; in that case Kubernetes Events are skipped (metrics + slog still cover the failure surface). deployRef points at the kube- controller Deployment so `kubectl describe deploy kube-controller` surfaces renewal Events.
func (*CertRenewer) NeedLeaderElection ¶
func (r *CertRenewer) NeedLeaderElection() bool
NeedLeaderElection signals controller-runtime to gate Start on leadership. Returning true means only the elected pod runs the renewer — the fsnotify watcher stays per-pod since each pod's in-process transport must be refreshed.
func (*CertRenewer) Start ¶
func (r *CertRenewer) Start(ctx context.Context) error
Start runs the renewer until ctx is cancelled. Implements sigs.k8s.io/controller-runtime/pkg/manager.Runnable.
The first check happens immediately at startup so a pod that comes up with a near-expiry cert renews on boot rather than waiting up to a full interval.
type IssueClientCertResponse ¶
type IssueClientCertResponse struct {
Certificate string `json:"certificate"`
PrivateKey string `json:"privateKey"`
CA string `json:"ca"`
}
IssueClientCertResponse is the response from the certificate issuance endpoint. Field names use camelCase to match gRPC-gateway's default protojson output.
type Option ¶
type Option func(*Options)
Option is a function that configures the APIServiceProxy.
func WithAPIHost ¶
WithAPIHost sets the Apoxy Cloud API host for certificate issuance.
func WithCertDir ¶
WithCertDir sets the directory the upstream client cert is mounted at. When non-empty, the proxy watches this dir for kubelet Secret-projection updates and hot-reloads the cert without a pod restart.
func WithClusterName ¶
WithClusterName sets the cluster name for the APIServiceProxy.
func WithKubeconfigPath ¶
WithKubeconfigPath sets the kubeconfig path for the APIServiceProxy.
func WithLocalMode ¶
WithLocalMode enables local-mode TLS handling: outbound HTTPS to cosmos and the apiserver proxy skips certificate verification, since the dev cluster uses cert-manager self-signed certs that aren't in the pod trust store. Never set this in production.
func WithNamespace ¶
WithNamespace sets the namespace for the APIServiceProxy.
func WithProjectID ¶
WithProjectID sets the project ID for the APIServiceProxy.
func WithRenewInterval ¶
WithRenewInterval sets how often the auto-renewer checks the live cert. A negative duration disables auto-renewal.
func WithRenewThreshold ¶
WithRenewThreshold sets the remaining-validity window below which the renewer issues a fresh cert.
func WithServiceName ¶
WithServiceName sets the Kubernetes Service name for the aggregated API endpoint.
type Options ¶
type Options struct {
ProjectID uuid.UUID
Namespace string
ServiceName string
ClusterName string
Token string
KubeconfigPath string
APIHost string
// LocalMode disables upstream TLS verification — cosmos-tls in dev is
// self-signed by cert-manager and not present in the pod's system
// trust store. Only set in dev installs (`apoxy k8s install --local`).
LocalMode bool
// CertDir is the path the apiz-cert Secret is mounted at inside the
// pod. When set, the proxy watches this directory for kubelet
// projections and hot-reloads the upstream client cert without a
// pod restart. When empty, hot-reload is disabled; rotation still
// works via the legacy pod-template-annotation restart.
CertDir string
// RenewInterval is how often the auto-renewer wakes up to check the
// live cert's remaining validity. Negative disables auto-renewal
// entirely (useful in tests and audited environments where rotation
// must be operator-driven). Zero falls back to DefaultRenewInterval.
RenewInterval time.Duration
// RenewThreshold is the remaining-validity window below which the
// renewer issues a fresh cert. Zero falls back to DefaultRenewThreshold.
RenewThreshold time.Duration
}
Options contains the configuration for the APIServiceProxy.