forked from open-policy-agent/opa
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathplugins.go
82 lines (68 loc) · 2.07 KB
/
plugins.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
// Copyright 2018 The OPA Authors. All rights reserved.
// Use of this source code is governed by an Apache2
// license that can be found in the LICENSE file.
// Specifies additional cmd commands that available to systems that can load plugins
// +build linux,cgo darwin,cgo
package cmd
import (
"fmt"
"os"
"path/filepath"
"plugin"
"github.com/spf13/cobra"
)
// registerSharedObjectsFromDir recursively loads all .so files in dir into OPA.
func registerSharedObjectsFromDir(dir string) error {
return filepath.Walk(dir, lambdaWalker(registerSharedObjectFromFile, ".so"))
}
// lambdaWalker returns a walkfunc that applies lambda to every file with extension ext. Ignores all other file types.
// Lambda should take the file path as its parameter.
func lambdaWalker(lambda func(string) error, ext string) filepath.WalkFunc {
walk := func(path string, f os.FileInfo, err error) error {
// if error occurs during traversal to path, exit and crash
if err != nil {
return err
}
// skip anything that is a directory
if f.IsDir() {
return nil
}
if filepath.Ext(path) == ext {
return lambda(path)
}
// ignore anything else
return nil
}
return walk
}
// loads the builtin from a file path
func registerSharedObjectFromFile(path string) error {
mod, err := plugin.Open(path)
if err != nil {
return err
}
initSym, err := mod.Lookup("Init")
if err != nil {
return err
}
// type assert init symbol
init, ok := initSym.(func() error)
if !ok {
return fmt.Errorf("symbol Init must be of type func() error")
}
// execute init
return init()
}
func init() {
var pluginDir string
// flag is persistent (can be loaded on all children commands)
RootCommand.PersistentFlags().StringVarP(&pluginDir, "plugin-dir", "", "", `set directory path to load built-in and plugin shared object files from`)
// Runs before *all* children commands
RootCommand.PersistentPreRunE = func(cmd *cobra.Command, args []string) error {
// only register custom plugins if directory specified
if pluginDir != "" {
return registerSharedObjectsFromDir(pluginDir)
}
return nil
}
}