github.com/argoproj/argo-events@v1.9.1/eventsources/persist/event_persist.go (about) 1 package persist 2 3 import ( 4 "context" 5 "fmt" 6 7 v1 "k8s.io/api/core/v1" 8 apierr "k8s.io/apimachinery/pkg/api/errors" 9 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 10 "k8s.io/client-go/kubernetes" 11 12 "github.com/argoproj/argo-events/common" 13 "github.com/argoproj/argo-events/pkg/apis/eventsource/v1alpha1" 14 ) 15 16 type EventPersist interface { 17 Save(event *Event) error 18 Get(key string) (*Event, error) 19 IsEnabled() bool 20 } 21 22 type Event struct { 23 EventKey string 24 EventPayload string 25 } 26 27 type ConfigMapPersist struct { 28 ctx context.Context 29 kubeClient kubernetes.Interface 30 name string 31 namespace string 32 createIfNotExist bool 33 } 34 35 func createConfigmap(ctx context.Context, client kubernetes.Interface, name, namespace string) (*v1.ConfigMap, error) { 36 cm := v1.ConfigMap{} 37 cm.Name = name 38 cm.Namespace = namespace 39 return client.CoreV1().ConfigMaps(namespace).Create(ctx, &cm, metav1.CreateOptions{}) 40 } 41 42 func NewConfigMapPersist(ctx context.Context, client kubernetes.Interface, configmap *v1alpha1.ConfigMapPersistence, namespace string) (EventPersist, error) { 43 if configmap == nil { 44 return nil, fmt.Errorf("persistence configuration is nil") 45 } 46 _, err := client.CoreV1().ConfigMaps(namespace).Get(ctx, configmap.Name, metav1.GetOptions{}) 47 if err != nil { 48 if apierr.IsNotFound(err) && configmap.CreateIfNotExist { 49 _, err = createConfigmap(ctx, client, configmap.Name, namespace) 50 if err != nil { 51 if !apierr.IsAlreadyExists(err) { 52 return nil, err 53 } 54 } 55 } else { 56 return nil, err 57 } 58 } 59 cmp := ConfigMapPersist{ 60 ctx: ctx, 61 kubeClient: client, 62 name: configmap.Name, 63 namespace: namespace, 64 createIfNotExist: configmap.CreateIfNotExist, 65 } 66 return &cmp, nil 67 } 68 69 func (cmp *ConfigMapPersist) IsEnabled() bool { 70 return true 71 } 72 73 func (cmp *ConfigMapPersist) Save(event *Event) error { 74 if event == nil { 75 return fmt.Errorf("event object is nil") 76 } 77 // Using Connect util func for backoff retry if K8s API returns error 78 err := common.DoWithRetry(&common.DefaultBackoff, func() error { 79 cm, err := cmp.kubeClient.CoreV1().ConfigMaps(cmp.namespace).Get(cmp.ctx, cmp.name, metav1.GetOptions{}) 80 if err != nil { 81 if apierr.IsNotFound(err) && cmp.createIfNotExist { 82 cm, err = createConfigmap(cmp.ctx, cmp.kubeClient, cmp.name, cmp.namespace) 83 if err != nil { 84 return err 85 } 86 } else { 87 return err 88 } 89 } 90 91 if len(cm.Data) == 0 { 92 cm.Data = make(map[string]string) 93 } 94 95 cm.Data[event.EventKey] = event.EventPayload 96 _, err = cmp.kubeClient.CoreV1().ConfigMaps(cmp.namespace).Update(cmp.ctx, cm, metav1.UpdateOptions{}) 97 98 return err 99 }) 100 101 if err != nil { 102 return err 103 } 104 return nil 105 } 106 107 func (cmp *ConfigMapPersist) Get(key string) (*Event, error) { 108 cm, err := cmp.kubeClient.CoreV1().ConfigMaps(cmp.namespace).Get(cmp.ctx, cmp.name, metav1.GetOptions{}) 109 if err != nil { 110 if apierr.IsNotFound(err) { 111 return nil, nil 112 } 113 return nil, err 114 } 115 payload, exist := cm.Data[key] 116 if !exist { 117 return nil, nil 118 } 119 return &Event{EventKey: key, EventPayload: payload}, nil 120 } 121 122 type NullPersistence struct { 123 } 124 125 func (n *NullPersistence) Save(event *Event) error { 126 return nil 127 } 128 129 func (n *NullPersistence) Get(key string) (*Event, error) { 130 return nil, nil 131 } 132 133 func (cmp *NullPersistence) IsEnabled() bool { 134 return false 135 }