mirror of
https://github.com/actions/actions-runner-controller.git
synced 2025-12-11 03:57:01 +00:00
Add POC of GitHub Webhook Delivery Forwarder (#682)
* Add POC of GitHub Webhook Delivery Forwarder * multi-forwarder and ctrl-c existing and fix for non-woring http post * Rename source files * Extract signal handling into a dedicated source file * Faster ctrl-c handling * Enable automatic creation of repo hook on startup * Add support for forwarding org hook deliveries * Set hook secret on hook creation via envvar (HOOK_SECRET) * Fix org hook support * Fix HOOK_SECRET for consistency * Refactor to prepare for custom log position provider * Refactor to extract inmemory log position provider * Add configmap-based log position provider * Rename githubwebhookdeliveryforwarder to hookdeliveryforwarder * Refactor to rename LogPositionProvider to Checkpointer and extract ConfigMap checkpointer into a dedicated pkg * Refactor to extract logger initialization * Add hookdeliveryforwarder README and bump go-github to unreleased ver
This commit is contained in:
100
pkg/hookdeliveryforwarder/configmap/checkpointer.go
Normal file
100
pkg/hookdeliveryforwarder/configmap/checkpointer.go
Normal file
@@ -0,0 +1,100 @@
|
||||
package configmap
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
kerrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
|
||||
"github.com/actions-runner-controller/actions-runner-controller/pkg/hookdeliveryforwarder"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
)
|
||||
|
||||
type ConfigMapCheckpointer struct {
|
||||
Name string
|
||||
NS string
|
||||
Client client.Client
|
||||
}
|
||||
|
||||
type state struct {
|
||||
DeliveredAt time.Time `json:"delivered_at"`
|
||||
ID int64 `json:"id"`
|
||||
}
|
||||
|
||||
func (p *ConfigMapCheckpointer) GetOrCreate(hookID int64) (*hookdeliveryforwarder.State, error) {
|
||||
var cm corev1.ConfigMap
|
||||
|
||||
if err := p.Client.Get(context.Background(), types.NamespacedName{Namespace: p.NS, Name: p.Name}, &cm); err != nil {
|
||||
if !kerrors.IsNotFound(err) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cm.Name = p.Name
|
||||
cm.Namespace = p.NS
|
||||
|
||||
if err := p.Client.Create(context.Background(), &cm); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
idStr := fmt.Sprintf("hook_%d", hookID)
|
||||
|
||||
var unmarshalled state
|
||||
|
||||
data, ok := cm.Data[idStr]
|
||||
|
||||
if ok {
|
||||
if err := json.Unmarshal([]byte(data), &unmarshalled); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
pos := &hookdeliveryforwarder.State{
|
||||
DeliveredAt: unmarshalled.DeliveredAt,
|
||||
ID: unmarshalled.ID,
|
||||
}
|
||||
|
||||
if pos.DeliveredAt.IsZero() {
|
||||
pos.DeliveredAt = time.Now()
|
||||
}
|
||||
|
||||
return pos, nil
|
||||
}
|
||||
|
||||
func (p *ConfigMapCheckpointer) Update(hookID int64, pos *hookdeliveryforwarder.State) error {
|
||||
var cm corev1.ConfigMap
|
||||
|
||||
if err := p.Client.Get(context.Background(), types.NamespacedName{Namespace: p.NS, Name: p.Name}, &cm); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var posData state
|
||||
|
||||
posData.DeliveredAt = pos.DeliveredAt
|
||||
posData.ID = pos.ID
|
||||
|
||||
idStr := fmt.Sprintf("hook_%d", hookID)
|
||||
|
||||
data, err := json.Marshal(posData)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
copy := cm.DeepCopy()
|
||||
|
||||
if copy.Data == nil {
|
||||
copy.Data = map[string]string{}
|
||||
}
|
||||
|
||||
copy.Data[idStr] = string(data)
|
||||
|
||||
if err := p.Client.Patch(context.Background(), copy, client.MergeFrom(&cm)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user