abril/serveis/altres/caddy/ingress/internal/controller/action_tls.go
2025-04-14 19:48:55 +00:00

125 lines
3.2 KiB
Go

package controller
import (
"os"
"path/filepath"
"github.com/caddyserver/ingress/internal/k8s"
apiv1 "k8s.io/api/core/v1"
)
var CertFolder = filepath.FromSlash("/etc/caddy/certs")
// SecretAddedAction provides an implementation of the action interface.
type SecretAddedAction struct {
resource *apiv1.Secret
}
// SecretUpdatedAction provides an implementation of the action interface.
type SecretUpdatedAction struct {
resource *apiv1.Secret
oldResource *apiv1.Secret
}
// SecretDeletedAction provides an implementation of the action interface.
type SecretDeletedAction struct {
resource *apiv1.Secret
}
// onSecretAdded runs when a TLS secret resource is added to the cluster.
func (c *CaddyController) onSecretAdded(obj *apiv1.Secret) {
if k8s.IsManagedTLSSecret(obj, c.resourceStore.Ingresses) {
c.syncQueue.Add(SecretAddedAction{
resource: obj,
})
}
}
// onSecretUpdated is run when a TLS secret resource is updated in the cluster.
func (c *CaddyController) onSecretUpdated(old *apiv1.Secret, new *apiv1.Secret) {
if k8s.IsManagedTLSSecret(new, c.resourceStore.Ingresses) {
c.syncQueue.Add(SecretUpdatedAction{
resource: new,
oldResource: old,
})
}
}
// onSecretDeleted is run when a TLS secret resource is deleted from the cluster.
func (c *CaddyController) onSecretDeleted(obj *apiv1.Secret) {
c.syncQueue.Add(SecretDeletedAction{
resource: obj,
})
}
// writeFile writes a secret to a .pem file on disk.
func writeFile(s *apiv1.Secret) error {
content := make([]byte, 0)
for _, cert := range s.Data {
content = append(content, cert...)
}
err := os.WriteFile(filepath.Join(CertFolder, s.Name+".pem"), content, 0644)
if err != nil {
return err
}
return nil
}
func (r SecretAddedAction) handle(c *CaddyController) error {
c.logger.Infof("TLS secret created (%s/%s)", r.resource.Namespace, r.resource.Name)
return writeFile(r.resource)
}
func (r SecretUpdatedAction) handle(c *CaddyController) error {
c.logger.Infof("TLS secret updated (%s/%s)", r.resource.Namespace, r.resource.Name)
return writeFile(r.resource)
}
func (r SecretDeletedAction) handle(c *CaddyController) error {
c.logger.Infof("TLS secret deleted (%s/%s)", r.resource.Namespace, r.resource.Name)
return os.Remove(filepath.Join(CertFolder, r.resource.Name+".pem"))
}
// watchTLSSecrets Start listening to TLS secrets if at least one ingress needs it.
// It will sync the CertFolder with TLS secrets
func (c *CaddyController) watchTLSSecrets() error {
if c.informers.TLSSecret == nil && c.resourceStore.HasManagedTLS() {
// Init informers
params := k8s.TLSSecretParams{
InformerFactory: c.factories.WatchedNamespace,
}
c.informers.TLSSecret = k8s.WatchTLSSecrets(params, k8s.TLSSecretHandlers{
AddFunc: c.onSecretAdded,
UpdateFunc: c.onSecretUpdated,
DeleteFunc: c.onSecretDeleted,
})
// Run it
go c.informers.TLSSecret.Run(c.stopChan)
// Sync secrets
secrets, err := k8s.ListTLSSecrets(params, c.resourceStore.Ingresses)
if err != nil {
return err
}
if _, err := os.Stat(CertFolder); os.IsNotExist(err) {
err = os.MkdirAll(CertFolder, 0755)
if err != nil {
return err
}
}
for _, secret := range secrets {
if err := writeFile(secret); err != nil {
return err
}
}
}
return nil
}