-
Notifications
You must be signed in to change notification settings - Fork 41
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add script processor using Tengo (#428)
- Implement a new 'script' processor with 'tengo' as the only supported script engine. - Add internal packages for translating asset proto value into map[string]interface{} and for updating asset proto value with the given map.
- Loading branch information
1 parent
6495614
commit 6cf9737
Showing
17 changed files
with
1,331 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -32,3 +32,5 @@ meteor-plugin-* | |
|
||
# build | ||
/dist | ||
|
||
.playground |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package tengoutil | ||
|
||
import ( | ||
"github.com/d5/tengo/v2" | ||
"github.com/d5/tengo/v2/stdlib" | ||
) | ||
|
||
const ( | ||
maxAllocs = 5000 | ||
maxConsts = 500 | ||
) | ||
|
||
func NewSecureScript(input []byte) *tengo.Script { | ||
s := tengo.NewScript(input) | ||
|
||
s.SetImports(stdlib.GetModuleMap(stdlib.AllModuleNames()...)) | ||
s.SetMaxAllocs(maxAllocs) | ||
s.SetMaxConstObjects(maxConsts) | ||
|
||
return s | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
//go:build plugins | ||
// +build plugins | ||
|
||
package tengoutil | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/MakeNowJust/heredoc" | ||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestNewSecureScript(t *testing.T) { | ||
t.Run("Allows import of builtin modules", func(t *testing.T) { | ||
s := NewSecureScript(([]byte)(heredoc.Doc(` | ||
math := import("math") | ||
os := import("os") | ||
text := import("text") | ||
times := import("times") | ||
rand := import("rand") | ||
fmt := import("fmt") | ||
json := import("json") | ||
base64 := import("base64") | ||
hex := import("hex") | ||
enum := import("enum") | ||
`))) | ||
_, err := s.Compile() | ||
assert.NoError(t, err) | ||
}) | ||
|
||
t.Run("File import disallowed", func(t *testing.T) { | ||
s := NewSecureScript(([]byte)(`sum := import("./testdata/sum")`)) | ||
_, err := s.Compile() | ||
assert.ErrorContains(t, err, "Compile Error: module './testdata/sum' not found") | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
package structmap | ||
|
||
import ( | ||
"fmt" | ||
|
||
v1beta2 "github.com/odpf/meteor/models/odpf/assets/v1beta2" | ||
"google.golang.org/protobuf/reflect/protoregistry" | ||
"google.golang.org/protobuf/types/known/anypb" | ||
) | ||
|
||
type AssetWrapper struct { | ||
A *v1beta2.Asset | ||
} | ||
|
||
func (w AssetWrapper) AsMap() (map[string]interface{}, error) { | ||
v, err := AsMap(w.A) | ||
if err != nil { | ||
return nil, fmt.Errorf("structmap: asset as map: %w", err) | ||
} | ||
|
||
m, ok := v.(map[string]interface{}) | ||
if !ok { | ||
return nil, fmt.Errorf("structmap: asset as map: unexpected type for asset map: %T", v) | ||
} | ||
|
||
return m, err | ||
} | ||
|
||
func (w *AssetWrapper) OverwriteWith(m map[string]interface{}) error { | ||
dataMap, ok := m["data"].(map[string]interface{}) | ||
if !ok { | ||
return fmt.Errorf("structmap: overwrite asset: unexpected type for asset data: %T", m["data"]) | ||
} | ||
|
||
mt, err := protoregistry.GlobalTypes.FindMessageByName(w.A.Data.MessageName()) | ||
if err != nil { | ||
return fmt.Errorf("structmap: overwrite asset: resolve type by full name %s: %w", w.A.Data.MessageName(), err) | ||
} | ||
|
||
msg := mt.New().Interface() | ||
delete(dataMap, "@type") | ||
if err := AsStruct(m["data"], &msg); err != nil { | ||
return fmt.Errorf("structmap: overwrite asset: decode asset data: %w", err) | ||
} | ||
|
||
delete(m, "data") | ||
if err := AsStruct(m, w.A); err != nil { | ||
return fmt.Errorf("structmap: overwrite asset: decode asset: %w", err) | ||
} | ||
|
||
data, err := anypb.New(msg) | ||
if err != nil { | ||
return fmt.Errorf("structmap: overwrite asset: marshal data as any: %w", err) | ||
} | ||
|
||
w.A.Data = data | ||
|
||
return nil | ||
} |
Oops, something went wrong.