kubelatte-ce
Форк от sbertech/kubelatte-ce
112 строк · 2.8 Кб
1package plugins
2
3import (
4"context"
5"fmt"
6"github.com/traefik/yaegi/interp"
7"github.com/traefik/yaegi/stdlib"
8"gitverse.ru/synapse/kubelatte/pkg/observability/logger"
9"gitverse.ru/synapse/kubelatte/pkg/util/env"
10"gopkg.in/yaml.v2"
11"os"
12)
13
14const DirCommon = "./config/plugins"
15
16var DirExtra = "./config/plugins/extra"
17
18var PluginsController = Manager{}
19
20type Manager struct {
21plugins []Plugin
22}
23
24type Plugin struct {
25PluginName string `yaml:"name"`
26Data string `yaml:"data"`
27Cached func(interface{}) interface{}
28}
29
30func (m *Manager) Start() {
31log := logger.FromContext(context.Background())
32log.Debug("[PluginManager] Plugin manager started")
33if env.DirPlugin != "" {
34DirExtra = env.DirPlugin
35}
36
37m.Load()
38}
39
40func (m *Manager) Load() {
41m.LoadPluginsFromDir(DirCommon)
42m.LoadPluginsFromDir(DirExtra)
43}
44
45func (m *Manager) LoadPluginsFromDir(path string) {
46log := logger.FromContext(context.Background())
47log.Debugf("[PluginManager] Load plugins from dir %s", path)
48entries, err := os.ReadDir(path)
49if err != nil {
50log.Errorf("[PluginManager] Load plugins error %s", err.Error())
51}
52for _, e := range entries {
53if e.IsDir() {
54continue
55}
56
57file, err := os.ReadFile(fmt.Sprintf("%s/%s", path, e.Name()))
58if err != nil {
59log.Errorf("[PluginManager] Load plugin %s error: %s", e.Name(), err.Error())
60continue
61}
62var plugin Plugin
63err = yaml.Unmarshal(file, &plugin)
64if err != nil {
65log.Errorf("[PluginManager] Parse plugin %s error: %s", e.Name(), err.Error())
66continue
67}
68plugin.Cached, err = m.Precompile(plugin.PluginName, plugin.Data)
69if err != nil {
70log.Errorf("[PluginManager] Precompile plugin %s error: %s", e.Name(), err.Error())
71continue
72}
73m.plugins = append(m.plugins, plugin)
74}
75}
76
77func (m *Manager) Precompile(name, data string) (func(interface{}) interface{}, error) {
78log := logger.FromContext(context.Background())
79i := interp.New(interp.Options{})
80
81err := i.Use(stdlib.Symbols)
82if err != nil {
83log.Errorf("[PluginManager] Compile plugin %s error: %s", name, err.Error())
84return nil, err
85}
86
87_, err = i.Eval(data)
88if err != nil {
89log.Errorf("[PluginManager] Compile plugin %s error: %s", name, err.Error())
90return nil, err
91}
92
93v, err := i.Eval("plugin.Logic")
94if err != nil {
95log.Errorf("[PluginManager] Logic plugin %s error: %s", name, err.Error())
96return nil, err
97}
98
99return v.Interface().(func(interface{}) interface{}), nil
100}
101
102func (m *Manager) Process(pluginName string, object interface{}) (interface{}, error) {
103log := logger.FromContext(context.Background())
104log.Debugf("[PluginManager] Process logic plugin %s", pluginName)
105for _, plugin := range m.plugins {
106if plugin.PluginName == pluginName {
107r := plugin.Cached(object)
108return r, nil
109}
110}
111return nil, fmt.Errorf("plugin not found")
112}
113