94 lines
2.3 KiB
Go
94 lines
2.3 KiB
Go
/*
|
|
Copyright 2022 The Kruise Authors.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
package luamanager
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"time"
|
|
|
|
lua "github.com/yuin/gopher-lua"
|
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
|
)
|
|
|
|
type LuaManager struct{}
|
|
|
|
func (m *LuaManager) RunLuaScript(obj *unstructured.Unstructured, script string) (*lua.LState, error) {
|
|
l := lua.NewState(lua.Options{SkipOpenLibs: true})
|
|
defer l.Close()
|
|
for _, pair := range []struct {
|
|
n string
|
|
f lua.LGFunction
|
|
}{
|
|
{lua.MathLibName, lua.OpenMath},
|
|
{lua.BaseLibName, lua.OpenBase},
|
|
{lua.TabLibName, lua.OpenTable},
|
|
{lua.StringLibName, lua.OpenString},
|
|
{JsonLibName, OpenJson},
|
|
} {
|
|
if err := l.CallByParam(lua.P{
|
|
Fn: l.NewFunction(pair.f),
|
|
NRet: 0,
|
|
Protect: true,
|
|
}, lua.LString(pair.n)); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
|
|
defer cancel()
|
|
l.SetContext(ctx)
|
|
objectValue := decodeValue(l, obj.Object)
|
|
l.SetGlobal("obj", objectValue)
|
|
err := l.DoString(script)
|
|
return l, err
|
|
}
|
|
|
|
func decodeValue(L *lua.LState, value interface{}) lua.LValue {
|
|
switch converted := value.(type) {
|
|
case bool:
|
|
return lua.LBool(converted)
|
|
case float64:
|
|
return lua.LNumber(converted)
|
|
case string:
|
|
return lua.LString(converted)
|
|
case json.Number:
|
|
return lua.LString(converted)
|
|
case int:
|
|
return lua.LNumber(converted)
|
|
case int32:
|
|
return lua.LNumber(converted)
|
|
case int64:
|
|
return lua.LNumber(converted)
|
|
case []interface{}:
|
|
arr := L.CreateTable(len(converted), 0)
|
|
for _, item := range converted {
|
|
arr.Append(decodeValue(L, item))
|
|
}
|
|
return arr
|
|
case map[string]interface{}:
|
|
tbl := L.CreateTable(0, len(converted))
|
|
for key, item := range converted {
|
|
tbl.RawSetH(lua.LString(key), decodeValue(L, item))
|
|
}
|
|
return tbl
|
|
case nil:
|
|
return lua.LNil
|
|
}
|
|
|
|
return lua.LNil
|
|
}
|