mirror of
https://github.com/stakater/Reloader.git
synced 2026-08-21 04:56:36 +00:00
113 lines
3.6 KiB
Go
113 lines
3.6 KiB
Go
package metadata
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"os"
|
|
|
|
"github.com/go-logr/logr"
|
|
corev1 "k8s.io/api/core/v1"
|
|
"k8s.io/apimachinery/pkg/api/errors"
|
|
"k8s.io/apimachinery/pkg/runtime"
|
|
"k8s.io/client-go/rest"
|
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
|
|
|
"github.com/stakater/Reloader/internal/pkg/workload"
|
|
"github.com/stakater/Reloader/pkg/config"
|
|
)
|
|
|
|
// Publisher handles creating and updating the metadata ConfigMap.
|
|
type Publisher struct {
|
|
client client.Client
|
|
cfg *config.Config
|
|
log logr.Logger
|
|
}
|
|
|
|
// NewPublisher creates a new Publisher.
|
|
func NewPublisher(c client.Client, cfg *config.Config, log logr.Logger) *Publisher {
|
|
return &Publisher{
|
|
client: c,
|
|
cfg: cfg,
|
|
log: log,
|
|
}
|
|
}
|
|
|
|
// Publish creates or updates the metadata ConfigMap.
|
|
func (p *Publisher) Publish(ctx context.Context) error {
|
|
namespace := os.Getenv(EnvReloaderNamespace)
|
|
if namespace == "" {
|
|
p.log.Info("RELOADER_NAMESPACE is not set, skipping meta info configmap creation")
|
|
return nil
|
|
}
|
|
|
|
metaInfo := NewMetaInfo(p.cfg)
|
|
configMap := metaInfo.ToConfigMap()
|
|
|
|
existing := &corev1.ConfigMap{}
|
|
err := p.client.Get(
|
|
ctx, client.ObjectKey{
|
|
Name: ConfigMapName,
|
|
Namespace: namespace,
|
|
}, existing,
|
|
)
|
|
|
|
if err != nil {
|
|
if !errors.IsNotFound(err) {
|
|
return fmt.Errorf("failed to get existing meta info configmap: %w", err)
|
|
}
|
|
p.log.Info("Creating meta info configmap")
|
|
if err := p.client.Create(ctx, configMap, client.FieldOwner(workload.FieldManager)); err != nil {
|
|
return fmt.Errorf("failed to create meta info configmap: %w", err)
|
|
}
|
|
p.log.Info("Meta info configmap created successfully")
|
|
return nil
|
|
}
|
|
|
|
p.log.Info("Meta info configmap already exists, updating it")
|
|
existing.Data = configMap.Data
|
|
existing.Labels = configMap.Labels
|
|
if err := p.client.Update(ctx, existing, client.FieldOwner(workload.FieldManager)); err != nil {
|
|
return fmt.Errorf("failed to update meta info configmap: %w", err)
|
|
}
|
|
p.log.Info("Meta info configmap updated successfully")
|
|
return nil
|
|
}
|
|
|
|
// PublishMetaInfoConfigMap is a convenience function that creates a Publisher and calls Publish.
|
|
func PublishMetaInfoConfigMap(ctx context.Context, c client.Client, cfg *config.Config, log logr.Logger) error {
|
|
publisher := NewPublisher(c, cfg, log)
|
|
return publisher.Publish(ctx)
|
|
}
|
|
|
|
// Runnable returns a controller-runtime Runnable that publishes the meta-info
|
|
// ConfigMap when the manager starts. It builds its own uncached client from the
|
|
// given rest config and scheme: the ConfigMap lives in Reloader's own namespace,
|
|
// which the manager cache does not cover in scoped mode, so a cache-backed client
|
|
// cannot read or write it there. Meta-info is internal instance metadata and is
|
|
// always published regardless of which resources are watched.
|
|
func Runnable(restConfig *rest.Config, scheme *runtime.Scheme, cfg *config.Config, log logr.Logger) RunnableFunc {
|
|
return func(ctx context.Context) error {
|
|
c, err := client.New(restConfig, client.Options{Scheme: scheme})
|
|
if err != nil {
|
|
log.Error(err, "Failed to create client for meta info configmap publisher")
|
|
// Non-fatal, don't return error to avoid crashing the manager
|
|
<-ctx.Done()
|
|
return nil
|
|
}
|
|
if err := PublishMetaInfoConfigMap(ctx, c, cfg, log); err != nil {
|
|
log.Error(err, "Failed to create metadata ConfigMap")
|
|
// Non-fatal, don't return error to avoid crashing the manager
|
|
}
|
|
<-ctx.Done()
|
|
return nil
|
|
}
|
|
}
|
|
|
|
// RunnableFunc is a function that implements the controller-runtime Runnable interface.
|
|
type RunnableFunc func(context.Context) error
|
|
|
|
// Start implements the Runnable interface.
|
|
func (r RunnableFunc) Start(ctx context.Context) error {
|
|
return r(ctx)
|
|
}
|