From 8e4fcf82e02091b8dd31355e3b943cc7b782ac00 Mon Sep 17 00:00:00 2001 From: Gustavo Carvalho Date: Fri, 29 Aug 2025 08:52:21 -0300 Subject: [PATCH 1/3] feat: support for workflows Signed-off-by: Gustavo Carvalho --- .../destination_workflowruntemplate_types.go | 27 +++ api/v1alpha1/reloader_types.go | 2 + api/v1alpha1/zz_generated.deepcopy.go | 37 ++++ .../reloader.external-secrets.io_configs.yaml | 120 +++++++++++++ internal/handler/schema/schema.go | 1 + internal/handler/workflow/handler.go | 162 ++++++++++++++++++ internal/handler/workflow/provider.go | 27 +++ 7 files changed, 376 insertions(+) create mode 100644 api/v1alpha1/destination_workflowruntemplate_types.go create mode 100644 internal/handler/workflow/handler.go create mode 100644 internal/handler/workflow/provider.go diff --git a/api/v1alpha1/destination_workflowruntemplate_types.go b/api/v1alpha1/destination_workflowruntemplate_types.go new file mode 100644 index 0000000..a4c6632 --- /dev/null +++ b/api/v1alpha1/destination_workflowruntemplate_types.go @@ -0,0 +1,27 @@ +package v1alpha1 + +import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + +// Defines a WorkflowRunTemplateDestination. Behavior is an annotations patch. +// Default UpdateStrategy is annotations patch to trigger Workflow reconcile. +// Default MatchStrategy is matching secret-key with any of: +// * Equality against `spec.data.remoteRef.key` +// * Equality against `spec.dataFrom.remoteRef.key` +// * Regexp against `spec.dataFrom.find.name.regexp` +type WorkflowRunTemplateDestination struct { + // NamespaceSelectors selects namespaces based on labels. + // The manifest must reside in a namespace that matches at least one of these selectors. + // +optional + NamespaceSelectors []metav1.LabelSelector `json:"namespaceSelectors,omitempty"` + + // LabelSelectors selects resources based on their labels. + // The resource must satisfy all conditions defined in this selector. + // Supports both matchLabels and matchExpressions for advanced filtering. + // +optional + LabelSelectors *metav1.LabelSelector `json:"labelSelectors,omitempty"` + + // Names specifies a list of resource names to watch. + // The resource must have a name that matches one of these entries. + // +optional + Names []string `json:"names,omitempty"` +} diff --git a/api/v1alpha1/reloader_types.go b/api/v1alpha1/reloader_types.go index 582e219..4a029a8 100644 --- a/api/v1alpha1/reloader_types.go +++ b/api/v1alpha1/reloader_types.go @@ -79,6 +79,8 @@ type DestinationToWatch struct { // +kubebuilder:validation:Enum=ExternalSecret;Deployment;PushSecret Type string `json:"type"` // +optional + WorkflowRunTemplate *WorkflowRunTemplateDestination `json:"workflowRunTemplate,omitempty"` + // +optional ExternalSecret *ExternalSecretDestination `json:"externalSecret,omitempty"` // +optional PushSecret *PushSecretDestination `json:"pushSecret,omitempty"` diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 6f80f68..4e3f80c 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -296,6 +296,11 @@ func (in *DeploymentDestination) DeepCopy() *DeploymentDestination { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *DestinationToWatch) DeepCopyInto(out *DestinationToWatch) { *out = *in + if in.Workflow != nil { + in, out := &in.Workflow, &out.Workflow + *out = new(WorkflowDestination) + (*in).DeepCopyInto(*out) + } if in.ExternalSecret != nil { in, out := &in.ExternalSecret, &out.ExternalSecret *out = new(ExternalSecretDestination) @@ -935,3 +940,35 @@ func (in *WebhookConfig) DeepCopy() *WebhookConfig { in.DeepCopyInto(out) return out } + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *WorkflowDestination) DeepCopyInto(out *WorkflowDestination) { + *out = *in + if in.NamespaceSelectors != nil { + in, out := &in.NamespaceSelectors, &out.NamespaceSelectors + *out = make([]v1.LabelSelector, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.LabelSelectors != nil { + in, out := &in.LabelSelectors, &out.LabelSelectors + *out = new(v1.LabelSelector) + (*in).DeepCopyInto(*out) + } + if in.Names != nil { + in, out := &in.Names, &out.Names + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkflowDestination. +func (in *WorkflowDestination) DeepCopy() *WorkflowDestination { + if in == nil { + return nil + } + out := new(WorkflowDestination) + in.DeepCopyInto(out) + return out +} diff --git a/config/crd/bases/reloader.external-secrets.io_configs.yaml b/config/crd/bases/reloader.external-secrets.io_configs.yaml index 668448e..61558fb 100644 --- a/config/crd/bases/reloader.external-secrets.io_configs.yaml +++ b/config/crd/bases/reloader.external-secrets.io_configs.yaml @@ -491,6 +491,126 @@ spec: the next object type: string type: object + workflow: + description: |- + Defines a WorkflowDestination. Behavior is an annotations patch. + Default UpdateStrategy is annotations patch to trigger Workflow reconcile. + Default MatchStrategy is matching secret-key with any of: + * Equality against `spec.data.remoteRef.key` + * Equality against `spec.dataFrom.remoteRef.key` + * Regexp against `spec.dataFrom.find.name.regexp` + properties: + labelSelectors: + description: |- + LabelSelectors selects resources based on their labels. + The resource must satisfy all conditions defined in this selector. + Supports both matchLabels and matchExpressions for advanced filtering. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + names: + description: |- + Names specifies a list of resource names to watch. + The resource must have a name that matches one of these entries. + items: + type: string + type: array + namespaceSelectors: + description: |- + NamespaceSelectors selects namespaces based on labels. + The manifest must reside in a namespace that matches at least one of these selectors. + items: + description: |- + A label selector is a label query over a set of resources. The result of matchLabels and + matchExpressions are ANDed. An empty label selector matches all objects. A null + label selector matches no objects. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: array + type: object required: - type type: object diff --git a/internal/handler/schema/schema.go b/internal/handler/schema/schema.go index 3fc2a41..a72bda8 100644 --- a/internal/handler/schema/schema.go +++ b/internal/handler/schema/schema.go @@ -13,6 +13,7 @@ const ( EXTERNAL_SECRET = "ExternalSecret" PUSH_SECRET = "PushSecret" DEPLOYMENT = "Deployment" + WORKFLOW = "Workflow" ) type ApplyFn func(obj client.Object, event events.SecretRotationEvent) error diff --git a/internal/handler/workflow/handler.go b/internal/handler/workflow/handler.go new file mode 100644 index 0000000..c9d3231 --- /dev/null +++ b/internal/handler/workflow/handler.go @@ -0,0 +1,162 @@ +package workflow + +import ( + "context" + "errors" + "fmt" + + "github.com/external-secrets-inc/reloader/api/v1alpha1" + "github.com/external-secrets-inc/reloader/internal/events" + "github.com/external-secrets-inc/reloader/internal/handler/schema" + "github.com/external-secrets-inc/reloader/internal/util" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/labels" + kruntime "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/log" +) + +type Handler struct { + ctx context.Context + client client.Client + destinationCache v1alpha1.DestinationToWatch + applyFn schema.ApplyFn + referenceFn schema.ReferenceFn + waitForFn schema.WaitForFn +} + +func (h *Handler) Filter(destination *v1alpha1.DestinationToWatch, event events.SecretRotationEvent) ([]client.Object, error) { + objs := []client.Object{} + if destination.WorkflowRunTemplate == nil { + return nil, errors.New("destination isn't type Workflow") + } + logger := log.FromContext(h.ctx) + workflows := &unstructured.UnstructuredList{} + workflows.SetGroupVersionKind(kruntime.GroupVersionKind{ + Group: "workflow.external-secrets.io", + Version: "v1alpha1", + Kind: "WorkflowRunTemplateList", + }) + if err := h.client.List(h.ctx, workflows); err != nil { + return nil, fmt.Errorf("failed to list Workflows: %w", err) + } + for i := range workflows.Items { + wf := &workflows.Items[i] + isWatched, err := h.isResourceWatched(wf, h.destinationCache) + if err != nil { + logger.Error(err, "failed to check if Workflow is watched", "name", wf.GetName(), "namespace", wf.GetNamespace()) + continue + } + if isWatched { + objs = append(objs, wf) + } + } + return objs, nil +} + +func (h *Handler) Apply(obj client.Object, event events.SecretRotationEvent) error { + return h.applyFn(obj, event) +} + +func (h *Handler) _apply(es client.Object, event events.SecretRotationEvent) error { + logger := log.FromContext(h.ctx) + + annotations := es.GetAnnotations() + if annotations == nil { + annotations = make(map[string]string) + } + + annotations["reloader/last-rotated"] = event.RotationTimestamp + annotations["reloader/trigger-source"] = event.TriggerSource + + es.SetAnnotations(annotations) + + if err := h.client.Update(h.ctx, es); err != nil { + return fmt.Errorf("failed to update WorkflowRunTemplate:%w", err) + } + logger.V(1).Info("Annotated WorkflowRunTemplate", "name", es.GetName(), "namespace", es.GetNamespace()) + return nil +} + +// isResourceWatched determines if a single ExternalSecret matches any of the SecretsToWatch criteria. +func (h *Handler) isResourceWatched(obj client.Object, w v1alpha1.DestinationToWatch) (bool, error) { + watchCriteria := w.WorkflowRunTemplate + if watchCriteria == nil { + return false, errors.New("watch type is not Workflow") + } + // Preprocess NamespaceSelectors + namespaceSelectors := make([]labels.Selector, 0, len(watchCriteria.NamespaceSelectors)) + for _, nsSelector := range watchCriteria.NamespaceSelectors { + selector, err := metav1.LabelSelectorAsSelector(&nsSelector) + if err != nil { + return false, fmt.Errorf("invalid namespace selector: %v", err) + } + namespaceSelectors = append(namespaceSelectors, selector) + } + + // Preprocess LabelSelectors + var labelSelector labels.Selector + var err error + if watchCriteria.LabelSelectors != nil { + labelSelector, err = metav1.LabelSelectorAsSelector(watchCriteria.LabelSelectors) + if err != nil { + return false, fmt.Errorf("invalid label selector: %v", err) + } + } + + // Preprocess Names into a map + nameSet := make(map[string]struct{}) + for _, name := range watchCriteria.Names { + nameSet[name] = struct{}{} + } + + // Perform matching + namespaceMatch, err := util.MatchesAnyNamespaceSelector(h.ctx, obj, namespaceSelectors, h.client) + if err != nil { + return false, err + } + labelMatch, err := util.MatchesLabelSelectors(h.ctx, obj, labelSelector, h.client) + if err != nil { + return false, err + } + nameMatch := util.IsNameInList(obj, nameSet) + if namespaceMatch && labelMatch && nameMatch { + return true, nil + } + + return false, nil +} + +func (h *Handler) WaitFor(obj client.Object) error { + return h.waitForFn(obj) +} + +// _waitFor is a noop for ExternalSecrets +func (h *Handler) _waitFor(obj client.Object) error { + // ExternalSecrets handler does not need to wait for anything + return nil +} +func (h *Handler) References(obj client.Object, secretIdentifier string) (bool, error) { + return h.referenceFn(obj, secretIdentifier) +} + +// _references returns true always - as Workflows always need to be triggered on a new action. +func (h *Handler) _references(obj client.Object, secretIdentifier string) (bool, error) { + return true, nil +} + +func (h *Handler) WithApply(apply schema.ApplyFn) schema.Handler { + h.applyFn = apply + return h +} + +func (h *Handler) WithReference(ref schema.ReferenceFn) schema.Handler { + h.referenceFn = ref + return h +} + +func (h *Handler) WithWaitFor(waitFor schema.WaitForFn) schema.Handler { + h.waitForFn = waitFor + return h +} diff --git a/internal/handler/workflow/provider.go b/internal/handler/workflow/provider.go new file mode 100644 index 0000000..46745a1 --- /dev/null +++ b/internal/handler/workflow/provider.go @@ -0,0 +1,27 @@ +package workflow + +import ( + "context" + + "github.com/external-secrets-inc/reloader/api/v1alpha1" + "github.com/external-secrets-inc/reloader/internal/handler/schema" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +type Provider struct{} + +func (p *Provider) NewHandler(ctx context.Context, client client.Client, cache v1alpha1.DestinationToWatch) schema.Handler { + h := &Handler{ + ctx: ctx, + client: client, + destinationCache: cache, + } + h.applyFn = h._apply + h.referenceFn = h._references + h.waitForFn = h._waitFor + return h +} + +func init() { + schema.RegisterProvider(schema.WORKFLOW, &Provider{}) +} From 8a9b682a34b8d10160eb76f5335996742d3ecc35 Mon Sep 17 00:00:00 2001 From: Gustavo Carvalho Date: Fri, 29 Aug 2025 09:59:27 -0300 Subject: [PATCH 2/3] feat: support workflowruntemplates as destinations Signed-off-by: Gustavo Carvalho --- api/v1alpha1/reloader_types.go | 2 +- api/v1alpha1/zz_generated.deepcopy.go | 14 +++++++------- .../reloader.external-secrets.io_configs.yaml | 5 +++-- config/rbac/role.yaml | 10 ++++++++++ internal/controller/reloader_controller.go | 1 + internal/handler/register.go | 1 + internal/handler/schema/schema.go | 2 +- internal/handler/workflow/handler.go | 2 +- internal/listener/kubernetes/listener.go | 8 +++++++- 9 files changed, 32 insertions(+), 13 deletions(-) diff --git a/api/v1alpha1/reloader_types.go b/api/v1alpha1/reloader_types.go index 4a029a8..fd170ce 100644 --- a/api/v1alpha1/reloader_types.go +++ b/api/v1alpha1/reloader_types.go @@ -76,7 +76,7 @@ type NotificationSource struct { type DestinationToWatch struct { // Type specifies the type of destination to watch. // +required - // +kubebuilder:validation:Enum=ExternalSecret;Deployment;PushSecret + // +kubebuilder:validation:Enum=ExternalSecret;Deployment;PushSecret;WorkflowRunTemplate Type string `json:"type"` // +optional WorkflowRunTemplate *WorkflowRunTemplateDestination `json:"workflowRunTemplate,omitempty"` diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 4e3f80c..59b7146 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -296,9 +296,9 @@ func (in *DeploymentDestination) DeepCopy() *DeploymentDestination { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *DestinationToWatch) DeepCopyInto(out *DestinationToWatch) { *out = *in - if in.Workflow != nil { - in, out := &in.Workflow, &out.Workflow - *out = new(WorkflowDestination) + if in.WorkflowRunTemplate != nil { + in, out := &in.WorkflowRunTemplate, &out.WorkflowRunTemplate + *out = new(WorkflowRunTemplateDestination) (*in).DeepCopyInto(*out) } if in.ExternalSecret != nil { @@ -942,7 +942,7 @@ func (in *WebhookConfig) DeepCopy() *WebhookConfig { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *WorkflowDestination) DeepCopyInto(out *WorkflowDestination) { +func (in *WorkflowRunTemplateDestination) DeepCopyInto(out *WorkflowRunTemplateDestination) { *out = *in if in.NamespaceSelectors != nil { in, out := &in.NamespaceSelectors, &out.NamespaceSelectors @@ -963,12 +963,12 @@ func (in *WorkflowDestination) DeepCopyInto(out *WorkflowDestination) { } } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkflowDestination. -func (in *WorkflowDestination) DeepCopy() *WorkflowDestination { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkflowRunTemplateDestination. +func (in *WorkflowRunTemplateDestination) DeepCopy() *WorkflowRunTemplateDestination { if in == nil { return nil } - out := new(WorkflowDestination) + out := new(WorkflowRunTemplateDestination) in.DeepCopyInto(out) return out } diff --git a/config/crd/bases/reloader.external-secrets.io_configs.yaml b/config/crd/bases/reloader.external-secrets.io_configs.yaml index 61558fb..008d4bc 100644 --- a/config/crd/bases/reloader.external-secrets.io_configs.yaml +++ b/config/crd/bases/reloader.external-secrets.io_configs.yaml @@ -428,6 +428,7 @@ spec: - ExternalSecret - Deployment - PushSecret + - WorkflowRunTemplate type: string updateStrategy: description: UpdateStrategy. If not specified, will use each @@ -491,9 +492,9 @@ spec: the next object type: string type: object - workflow: + workflowRunTemplate: description: |- - Defines a WorkflowDestination. Behavior is an annotations patch. + Defines a WorkflowRunTemplateDestination. Behavior is an annotations patch. Default UpdateStrategy is annotations patch to trigger Workflow reconcile. Default MatchStrategy is matching secret-key with any of: * Equality against `spec.data.remoteRef.key` diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index ee69ef2..e887695 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -59,3 +59,13 @@ rules: - configs/finalizers verbs: - update +- apiGroups: + - workflows.external-secrets.io + resources: + - workflowruntemplates + verbs: + - get + - list + - patch + - update + - watch diff --git a/internal/controller/reloader_controller.go b/internal/controller/reloader_controller.go index f004637..a52401c 100644 --- a/internal/controller/reloader_controller.go +++ b/internal/controller/reloader_controller.go @@ -88,6 +88,7 @@ func (r *ReloaderReconciler) SetupWithManager(mgr ctrl.Manager) error { // +kubebuilder:rbac:groups=reloader.external-secrets.io,resources=configs/finalizers,verbs=update // For k8s ExternalSecrets and PushSecrets destination // +kubebuilder:rbac:groups=external-secrets.io,resources=externalsecrets;pushsecrets,verbs=get;list;watch;update;patch +// +kubebuilder:rbac:groups=workflows.external-secrets.io,resources=workflowruntemplates,verbs=get;list;watch;update;patch // For k8s Deployments destination // +kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;update;patch // +kubebuilder:rbac:groups=coordination.k8s.io,resources=leases,verbs=get;create;update;patch diff --git a/internal/handler/register.go b/internal/handler/register.go index 5de26f6..2815340 100644 --- a/internal/handler/register.go +++ b/internal/handler/register.go @@ -4,4 +4,5 @@ import ( _ "github.com/external-secrets-inc/reloader/internal/handler/deployment" _ "github.com/external-secrets-inc/reloader/internal/handler/externalsecret" _ "github.com/external-secrets-inc/reloader/internal/handler/pushsecret" + _ "github.com/external-secrets-inc/reloader/internal/handler/workflow" ) diff --git a/internal/handler/schema/schema.go b/internal/handler/schema/schema.go index a72bda8..8d3fc3c 100644 --- a/internal/handler/schema/schema.go +++ b/internal/handler/schema/schema.go @@ -13,7 +13,7 @@ const ( EXTERNAL_SECRET = "ExternalSecret" PUSH_SECRET = "PushSecret" DEPLOYMENT = "Deployment" - WORKFLOW = "Workflow" + WORKFLOW = "WorkflowRunTemplate" ) type ApplyFn func(obj client.Object, event events.SecretRotationEvent) error diff --git a/internal/handler/workflow/handler.go b/internal/handler/workflow/handler.go index c9d3231..a22cc53 100644 --- a/internal/handler/workflow/handler.go +++ b/internal/handler/workflow/handler.go @@ -34,7 +34,7 @@ func (h *Handler) Filter(destination *v1alpha1.DestinationToWatch, event events. logger := log.FromContext(h.ctx) workflows := &unstructured.UnstructuredList{} workflows.SetGroupVersionKind(kruntime.GroupVersionKind{ - Group: "workflow.external-secrets.io", + Group: "workflows.external-secrets.io", Version: "v1alpha1", Kind: "WorkflowRunTemplateList", }) diff --git a/internal/listener/kubernetes/listener.go b/internal/listener/kubernetes/listener.go index 1fc7d82..99335b6 100644 --- a/internal/listener/kubernetes/listener.go +++ b/internal/listener/kubernetes/listener.go @@ -25,6 +25,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/builder" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/handler" + metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" "sigs.k8s.io/controller-runtime/pkg/predicate" "sigs.k8s.io/controller-runtime/pkg/reconcile" ) @@ -56,7 +57,12 @@ func (h *Handler[T]) Start() error { if err != nil { return fmt.Errorf("could not create client set: %w", err) } - manager, err := ctrl.NewManager(cfg, ctrl.Options{}) + metricsServerOptions := metricsserver.Options{ + BindAddress: "0", + } + manager, err := ctrl.NewManager(cfg, ctrl.Options{ + Metrics: metricsServerOptions, + }) if err != nil { return fmt.Errorf("could not create manager: %w", err) } From 4d85403e7d87ccd0e6b7582d33868b8806bcf83e Mon Sep 17 00:00:00 2001 From: Gustavo Carvalho Date: Fri, 29 Aug 2025 10:16:38 -0300 Subject: [PATCH 3/3] fix: nolint Signed-off-by: Gustavo Carvalho --- internal/listener/pubsub/listener.go | 2 +- internal/listener/pubsub/provider.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/listener/pubsub/listener.go b/internal/listener/pubsub/listener.go index ece99e7..6a3037b 100644 --- a/internal/listener/pubsub/listener.go +++ b/internal/listener/pubsub/listener.go @@ -7,7 +7,7 @@ import ( "strings" "time" - "cloud.google.com/go/pubsub" + "cloud.google.com/go/pubsub" //nolint v1alpha1 "github.com/external-secrets-inc/reloader/api/v1alpha1" "github.com/external-secrets-inc/reloader/internal/events" "github.com/external-secrets-inc/reloader/internal/listener/schema" diff --git a/internal/listener/pubsub/provider.go b/internal/listener/pubsub/provider.go index 2169df8..506f3eb 100644 --- a/internal/listener/pubsub/provider.go +++ b/internal/listener/pubsub/provider.go @@ -5,7 +5,7 @@ import ( "errors" "fmt" - "cloud.google.com/go/pubsub" + "cloud.google.com/go/pubsub" //nolint v1alpha1 "github.com/external-secrets-inc/reloader/api/v1alpha1" "github.com/external-secrets-inc/reloader/internal/events" "github.com/external-secrets-inc/reloader/internal/listener/schema"