func convertNilsToNulls(object interface{}) { switch object := object.(type) { case map[string]interface{}: for key, obj := range object { switch obj := obj.(type) { case map[string]interface{}: convertNilsToNulls(obj) case []interface{}: convertNilsToNulls(obj) case nil: object[key] = otto.NullValue() } } case []interface{}: for key, obj := range object { switch obj := obj.(type) { case map[string]interface{}: convertNilsToNulls(obj) case []interface{}: convertNilsToNulls(obj) case nil: object[key] = otto.NullValue() } } } }
func (env *Environment) mockFunction(functionName string) { env.VM.Set(functionName, func(call otto.FunctionCall) otto.Value { responses := env.getFromOtto(functionName, "responses").([]otto.Value) requests := env.getFromOtto(functionName, "requests").([][]otto.Value) err := env.checkSpecified(functionName) if err != nil { call.Otto.Call("Fail", nil, err.Error()) } readableArguments := valueSliceToString(call.ArgumentList) if len(responses) == 0 { call.Otto.Call("Fail", nil, fmt.Sprintf("Unexpected call to %s(%v)", functionName, readableArguments)) } expectedArguments := requests[0] actualArguments := call.ArgumentList if !argumentsEqual(expectedArguments, actualArguments) { call.Otto.Call("Fail", nil, fmt.Sprintf("Wrong arguments for call %s(%v), expected %s", functionName, readableArguments, valueSliceToString(expectedArguments))) } response := responses[0] responses = responses[1:] env.setToOtto(functionName, "responses", responses) requests = requests[1:] env.setToOtto(functionName, "requests", requests) return response }) env.setToOtto(functionName, "requests", [][]otto.Value{}) env.setToOtto(functionName, "Expect", func(call otto.FunctionCall) otto.Value { requests := env.getFromOtto(functionName, "requests").([][]otto.Value) if len(call.ArgumentList) == 0 { call.Otto.Call("Fail", nil, "Expect() should be called with at least one argument") } requests = append(requests, call.ArgumentList) env.setToOtto(functionName, "requests", requests) function, _ := env.VM.Get(functionName) return function }) env.setToOtto(functionName, "responses", []otto.Value{}) env.setToOtto(functionName, "Return", func(call otto.FunctionCall) otto.Value { responses := env.getFromOtto(functionName, "responses").([]otto.Value) if len(call.ArgumentList) != 1 { call.Otto.Call("Fail", nil, "Return() should be called with exactly one argument") } responses = append(responses, call.ArgumentList[0]) env.setToOtto(functionName, "responses", responses) return otto.NullValue() }) env.mockedFunctions = append(env.mockedFunctions, functionName) }
//SetUp sets up vm to with environment func init() { gohanRemoteInit := func(env *Environment) { vm := env.VM builtins := map[string]interface{}{ "gohan_netconf_open": func(call otto.FunctionCall) otto.Value { if len(call.ArgumentList) != 2 { panic("Wrong number of arguments in gohan_netconf_open call.") } rawHost, _ := call.Argument(0).Export() host, ok := rawHost.(string) if !ok { return otto.NullValue() } rawUserName, _ := call.Argument(1).Export() userName, ok := rawUserName.(string) if !ok { return otto.NullValue() } config := util.GetConfig() publicKeyFile := config.GetString("ssh/key_file", "") if publicKeyFile == "" { return otto.NullValue() } sshConfig := &ssh.ClientConfig{ User: userName, Auth: []ssh.AuthMethod{ util.PublicKeyFile(publicKeyFile), }, } s, err := netconf.DialSSH(host, sshConfig) if err != nil { ThrowOttoException(&call, "Error during gohan_netconf_open: %s", err.Error()) } value, _ := vm.ToValue(s) return value }, "gohan_netconf_close": func(call otto.FunctionCall) otto.Value { if len(call.ArgumentList) != 1 { panic("Wrong number of arguments in gohan_netconf_close call.") } rawSession, _ := call.Argument(0).Export() s, ok := rawSession.(*netconf.Session) if !ok { ThrowOttoException(&call, "Error during gohan_netconf_close") } s.Close() return otto.NullValue() }, "gohan_netconf_exec": func(call otto.FunctionCall) otto.Value { if len(call.ArgumentList) != 2 { panic("Wrong number of arguments in gohan_netconf_exec call.") } rawSession, _ := call.Argument(0).Export() s, ok := rawSession.(*netconf.Session) if !ok { return otto.NullValue() } rawCommand, _ := call.Argument(1).Export() command, ok := rawCommand.(string) if !ok { return otto.NullValue() } reply, err := s.Exec(netconf.RawMethod(command)) resp := map[string]interface{}{} if err != nil { resp["status"] = "error" resp["output"] = err.Error() } else { resp["status"] = "success" resp["output"] = reply } value, _ := vm.ToValue(resp) return value }, "gohan_ssh_open": func(call otto.FunctionCall) otto.Value { if len(call.ArgumentList) != 2 { panic("Wrong number of arguments in gohan_netconf_open call.") } rawHost, _ := call.Argument(0).Export() host, ok := rawHost.(string) if !ok { return otto.NullValue() } rawUserName, _ := call.Argument(1).Export() userName, ok := rawUserName.(string) if !ok { return otto.NullValue() } config := util.GetConfig() publicKeyFile := config.GetString("ssh/key_file", "") if publicKeyFile == "" { return otto.NullValue() } sshConfig := &ssh.ClientConfig{ User: userName, Auth: []ssh.AuthMethod{ util.PublicKeyFile(publicKeyFile), }, } conn, err := ssh.Dial("tcp", host, sshConfig) if err != nil { ThrowOttoException(&call, "Error during gohan_ssh_open %s", err) } session, err := conn.NewSession() if err != nil { ThrowOttoException(&call, "Error during gohan_ssh_open %s", err) } value, _ := vm.ToValue(session) return value }, "gohan_ssh_close": func(call otto.FunctionCall) otto.Value { if len(call.ArgumentList) != 1 { panic("Wrong number of arguments in gohan_netconf_close call.") } rawSession, _ := call.Argument(0).Export() s, ok := rawSession.(*ssh.Session) if !ok { ThrowOttoException(&call, "Error during gohan_ssh_close") } s.Close() return otto.NullValue() }, "gohan_ssh_exec": func(call otto.FunctionCall) otto.Value { if len(call.ArgumentList) != 2 { panic("Wrong number of arguments in gohan_netconf_exec call.") } rawSession, _ := call.Argument(0).Export() s, ok := rawSession.(*ssh.Session) if !ok { return otto.NullValue() } rawCommand, _ := call.Argument(1).Export() command, ok := rawCommand.(string) if !ok { return otto.NullValue() } var stdoutBuf bytes.Buffer s.Stdout = &stdoutBuf err := s.Run(command) resp := map[string]interface{}{} if err != nil { resp["status"] = "error" resp["output"] = err.Error() } else { resp["status"] = "success" resp["output"] = stdoutBuf.String() } value, _ := vm.ToValue(resp) return value }, } for name, object := range builtins { vm.Set(name, object) } } RegistInit(gohanRemoteInit) }
func init() { gohanDBInit := func(env *Environment) { vm := env.VM builtins := map[string]interface{}{ "gohan_db_list": func(call otto.FunctionCall) otto.Value { VerifyCallArguments(&call, "gohan_db_list", 3) rawTransaction, _ := call.Argument(0).Export() transaction, ok := rawTransaction.(transaction.Transaction) if !ok { ThrowOttoException(&call, noTransactionErrorMessage) } schemaID := call.Argument(1).String() filterObj, _ := call.Argument(2).Export() var filter map[string]interface{} if filterObj != nil { filter = filterObj.(map[string]interface{}) } manager := schema.GetManager() schema, ok := manager.Schema(schemaID) if !ok { ThrowOttoException(&call, unknownSchemaErrorMesssageFormat, schemaID) } resources, _, err := transaction.List(schema, filter, nil) if err != nil { ThrowOttoException(&call, "Error during gohan_db_list: %s", err.Error()) } resp := []map[string]interface{}{} for _, resource := range resources { resp = append(resp, resource.Data()) } value, _ := vm.ToValue(resp) return value }, "gohan_db_fetch": func(call otto.FunctionCall) otto.Value { VerifyCallArguments(&call, "gohan_db_fetch", 4) rawTransaction, _ := call.Argument(0).Export() transaction, ok := rawTransaction.(transaction.Transaction) if !ok { ThrowOttoException(&call, noTransactionErrorMessage) } schemaID := call.Argument(1).String() ID := call.Argument(2).String() tenantID := call.Argument(3).String() manager := schema.GetManager() schema, ok := manager.Schema(schemaID) if !ok { ThrowOttoException(&call, unknownSchemaErrorMesssageFormat, schemaID) } var tenantFilter []string if tenantID != "" { tenantFilter = []string{tenantID} } resp, err := transaction.Fetch(schema, ID, tenantFilter) if err != nil { ThrowOttoException(&call, "Error during gohan_db_fetch: %s", err.Error()) } if resp == nil { otto.NullValue() } value, _ := vm.ToValue(resp.Data()) return value }, "gohan_db_create": func(call otto.FunctionCall) otto.Value { VerifyCallArguments(&call, "gohan_db_create", 3) rawTransaction, _ := call.Argument(0).Export() transaction, ok := rawTransaction.(transaction.Transaction) if !ok { ThrowOttoException(&call, noTransactionErrorMessage) } schemaID := call.Argument(1).String() data := ConvertOttoToGo(call.Argument(2)) dataMap, _ := data.(map[string]interface{}) manager := schema.GetManager() resource, err := manager.LoadResource(schemaID, dataMap) if err != nil { ThrowOttoException(&call, "Error during gohan_db_create: %s", err.Error()) } if err = transaction.Create(resource); err != nil { ThrowOttoException(&call, "Error during gohan_db_create: %s", err.Error()) } value, _ := vm.ToValue(resource.Data()) return value }, "gohan_db_update": func(call otto.FunctionCall) otto.Value { VerifyCallArguments(&call, "gohan_db_update", 3) rawTransaction, _ := call.Argument(0).Export() transaction, ok := rawTransaction.(transaction.Transaction) if !ok { ThrowOttoException(&call, noTransactionErrorMessage) } schemaID := call.Argument(1).String() data := ConvertOttoToGo(call.Argument(2)) dataMap, _ := data.(map[string]interface{}) manager := schema.GetManager() resource, err := manager.LoadResource(schemaID, dataMap) if err != nil { ThrowOttoException(&call, "Error during gohan_db_update: %s", err.Error()) } if err = transaction.Update(resource); err != nil { ThrowOttoException(&call, "Error during gohan_db_update: %s", err.Error()) } value, _ := vm.ToValue(resource.Data()) return value }, "gohan_db_state_update": func(call otto.FunctionCall) otto.Value { VerifyCallArguments(&call, "gohan_db_state_update", 3) rawTransaction, _ := call.Argument(0).Export() transaction, ok := rawTransaction.(transaction.Transaction) if !ok { ThrowOttoException(&call, noTransactionErrorMessage) } schemaID := call.Argument(1).String() data := ConvertOttoToGo(call.Argument(2)) dataMap, _ := data.(map[string]interface{}) manager := schema.GetManager() resource, err := manager.LoadResource(schemaID, dataMap) if err != nil { ThrowOttoException(&call, "Error during gohan_db_state_update: %s", err.Error()) } if err = transaction.StateUpdate(resource); err != nil { ThrowOttoException(&call, "Error during gohan_db_state_update: %s", err.Error()) } value, _ := vm.ToValue(resource.Data()) return value }, "gohan_db_delete": func(call otto.FunctionCall) otto.Value { VerifyCallArguments(&call, "gohan_db_delete", 3) rawTransaction, _ := call.Argument(0).Export() transaction, ok := rawTransaction.(transaction.Transaction) if !ok { ThrowOttoException(&call, noTransactionErrorMessage) } schemaID := call.Argument(1).String() ID := call.Argument(2).String() manager := schema.GetManager() schema, _ := manager.Schema(schemaID) if err := transaction.Delete(schema, ID); err != nil { ThrowOttoException(&call, "Error during gohan_db_delete: %s", err.Error()) } return otto.NullValue() }, "gohan_db_query": func(call otto.FunctionCall) otto.Value { VerifyCallArguments(&call, "gohan_db_query", 4) rawTransaction, _ := call.Argument(0).Export() transaction, ok := rawTransaction.(transaction.Transaction) if !ok { ThrowOttoException(&call, noTransactionErrorMessage) } schemaID := call.Argument(1).String() sqlString := call.Argument(2).String() rawArguments, _ := call.Argument(3).Export() manager := schema.GetManager() s, ok := manager.Schema(schemaID) if !ok { ThrowOttoException(&call, unknownSchemaErrorMesssageFormat, schemaID) } arguments, ok := rawArguments.([]interface{}) if !ok { ThrowOttoException(&call, "Gievn arguments is not []interface{}") } resources, err := transaction.Query(s, sqlString, arguments) if err != nil { ThrowOttoException(&call, "Error during gohan_db_query: %s", err.Error()) } resp := []map[string]interface{}{} for _, resource := range resources { resp = append(resp, resource.Data()) } value, _ := vm.ToValue(resp) return value }, "gohan_db_sql_make_columns": func(call otto.FunctionCall) otto.Value { VerifyCallArguments(&call, "gohan_db_query", 1) schemaID := call.Argument(0).String() manager := schema.GetManager() s, ok := manager.Schema(schemaID) if !ok { ThrowOttoException(&call, unknownSchemaErrorMesssageFormat, schemaID) } results := sql.MakeColumns(s, false) value, _ := vm.ToValue(results) return value }, } for name, object := range builtins { vm.Set(name, object) } } RegistInit(gohanDBInit) }
Context("Given environment", func() { BeforeEach(func() { env = otto.NewEnvironment(testDB, &middleware.FakeIdentity{}) env.SetUp() vm := env.VM builtins := map[string]interface{}{ "test_consume": func(call ottopkg.FunctionCall) ottopkg.Value { result := <-channel ottoResult, _ := vm.ToValue(result) return ottoResult }, "test_produce": func(call ottopkg.FunctionCall) ottopkg.Value { ottoProduct := otto.ConvertOttoToGo(call.Argument(0)) product := otto.ConvertOttoToGo(ottoProduct).(string) channel <- product return ottopkg.NullValue() }, } for name, object := range builtins { vm.Set(name, object) } Expect(env.Load("<race_test>", ` var produce = function() { for (var i = 0; i < 10; i++) { console.log("producing:", i); test_produce(i.toString()); } }; var consume = function() {
func init() { gohanDBInit := func(env *Environment) { vm := env.VM builtins := map[string]interface{}{ "gohan_db_transaction": func(call otto.FunctionCall) otto.Value { VerifyCallArguments(&call, "gohan_db_transaction", 0) tx, err := env.DataStore.Begin() if err != nil { ThrowOttoException(&call, "failed to start a transaction") } value, _ := vm.ToValue(tx) return value }, "gohan_db_list": func(call otto.FunctionCall) otto.Value { if len(call.ArgumentList) < 4 { defaultOrderKey, _ := otto.ToValue("") // no sorting call.ArgumentList = append(call.ArgumentList, defaultOrderKey) } if len(call.ArgumentList) < 5 { defaultLimit, _ := otto.ToValue(0) // no limit call.ArgumentList = append(call.ArgumentList, defaultLimit) } if len(call.ArgumentList) < 6 { defaultOffset, _ := otto.ToValue(0) // no offset call.ArgumentList = append(call.ArgumentList, defaultOffset) } VerifyCallArguments(&call, "gohan_db_list", 6) transaction, needCommit, err := env.GetOrCreateTransaction(call.Argument(0)) if err != nil { ThrowOttoException(&call, err.Error()) } if needCommit { defer transaction.Close() } schemaID, err := GetString(call.Argument(1)) if err != nil { ThrowOttoException(&call, err.Error()) } filter, err := GetMap(call.Argument(2)) if err != nil { ThrowOttoException(&call, err.Error()) } orderKey, err := GetString(call.Argument(3)) if err != nil { ThrowOttoException(&call, err.Error()) } rawLimit, err := GetInt64(call.Argument(4)) if err != nil { ThrowOttoException(&call, err.Error()) } limit := uint64(rawLimit) rawOffset, err := GetInt64(call.Argument(5)) if err != nil { ThrowOttoException(&call, err.Error()) } offset := uint64(rawOffset) resp, err := GohanDbList(transaction, schemaID, filter, orderKey, limit, offset) if err != nil { ThrowOttoException(&call, err.Error()) } value, _ := vm.ToValue(resp) return value }, "gohan_db_fetch": func(call otto.FunctionCall) otto.Value { VerifyCallArguments(&call, "gohan_db_fetch", 4) transaction, needCommit, err := env.GetOrCreateTransaction(call.Argument(0)) if err != nil { ThrowOttoException(&call, err.Error()) } if needCommit { defer transaction.Close() } schemaID, err := GetString(call.Argument(1)) if err != nil { ThrowOttoException(&call, err.Error()) } ID, err := GetString(call.Argument(2)) if err != nil { ThrowOttoException(&call, err.Error()) } tenantID, err := GetString(call.Argument(3)) if err != nil { ThrowOttoException(&call, err.Error()) } resp, err := GohanDbFetch(transaction, schemaID, ID, tenantID) if err != nil { ThrowOttoException(&call, err.Error()) } if resp == nil { otto.NullValue() } value, _ := vm.ToValue(resp.Data()) return value }, "gohan_db_state_fetch": func(call otto.FunctionCall) otto.Value { VerifyCallArguments(&call, "gohan_db_state_fetch", 4) transaction, needCommit, err := env.GetOrCreateTransaction(call.Argument(0)) if err != nil { ThrowOttoException(&call, err.Error()) } if needCommit { defer transaction.Close() } schemaID, err := GetString(call.Argument(1)) if err != nil { ThrowOttoException(&call, err.Error()) } ID, err := GetString(call.Argument(2)) if err != nil { ThrowOttoException(&call, err.Error()) } tenantID, err := GetString(call.Argument(3)) if err != nil { ThrowOttoException(&call, err.Error()) } data, err := GohanDbStateFetch(transaction, schemaID, ID, tenantID) if err != nil { ThrowOttoException(&call, err.Error()) } value, _ := vm.ToValue(data) return value }, "gohan_db_create": func(call otto.FunctionCall) otto.Value { VerifyCallArguments(&call, "gohan_db_create", 3) transaction, err := GetTransaction(call.Argument(0)) transaction, needCommit, err := env.GetOrCreateTransaction(call.Argument(0)) if err != nil { ThrowOttoException(&call, err.Error()) } if needCommit { defer transaction.Close() } schemaID, err := GetString(call.Argument(1)) if err != nil { ThrowOttoException(&call, err.Error()) } dataMap, err := GetMap(call.Argument(2)) if err != nil { ThrowOttoException(&call, err.Error()) } resource, err := GohanDbCreate(transaction, needCommit, schemaID, dataMap) if err != nil { ThrowOttoException(&call, err.Error()) } value, _ := vm.ToValue(resource.Data()) return value }, "gohan_db_update": func(call otto.FunctionCall) otto.Value { VerifyCallArguments(&call, "gohan_db_update", 3) transaction, needCommit, err := env.GetOrCreateTransaction(call.Argument(0)) if err != nil { ThrowOttoException(&call, err.Error()) } if needCommit { defer transaction.Close() } schemaID, err := GetString(call.Argument(1)) if err != nil { ThrowOttoException(&call, err.Error()) } dataMap, err := GetMap(call.Argument(2)) if err != nil { ThrowOttoException(&call, err.Error()) } resource, err := GohanDbUpdate(transaction, needCommit, schemaID, dataMap) if err != nil { ThrowOttoException(&call, err.Error()) } value, _ := vm.ToValue(resource.Data()) return value }, "gohan_db_state_update": func(call otto.FunctionCall) otto.Value { VerifyCallArguments(&call, "gohan_db_state_update", 3) transaction, needCommit, err := env.GetOrCreateTransaction(call.Argument(0)) if err != nil { ThrowOttoException(&call, err.Error()) } if needCommit { defer transaction.Close() } schemaID, err := GetString(call.Argument(1)) if err != nil { ThrowOttoException(&call, err.Error()) } dataMap, err := GetMap(call.Argument(2)) if err != nil { ThrowOttoException(&call, err.Error()) } resource, err := GohanDbStateUpdate(transaction, needCommit, schemaID, dataMap) if err != nil { ThrowOttoException(&call, err.Error()) } value, _ := vm.ToValue(resource.Data()) return value }, "gohan_db_delete": func(call otto.FunctionCall) otto.Value { VerifyCallArguments(&call, "gohan_db_delete", 3) transaction, needCommit, err := env.GetOrCreateTransaction(call.Argument(0)) if err != nil { ThrowOttoException(&call, err.Error()) } if needCommit { defer transaction.Close() } schemaID, err := GetString(call.Argument(1)) if err != nil { ThrowOttoException(&call, err.Error()) } ID, err := GetString(call.Argument(2)) if err != nil { ThrowOttoException(&call, err.Error()) } err = GohanDbDelete(transaction, needCommit, schemaID, ID) if err != nil { ThrowOttoException(&call, err.Error()) } return otto.NullValue() }, "gohan_db_query": func(call otto.FunctionCall) otto.Value { VerifyCallArguments(&call, "gohan_db_query", 4) transaction, needCommit, err := env.GetOrCreateTransaction(call.Argument(0)) if err != nil { ThrowOttoException(&call, err.Error()) } if needCommit { defer transaction.Close() } schemaID, err := GetString(call.Argument(1)) if err != nil { ThrowOttoException(&call, err.Error()) } sqlString, err := GetString(call.Argument(2)) if err != nil { ThrowOttoException(&call, err.Error()) } arguments, err := GetList(call.Argument(3)) if err != nil { ThrowOttoException(&call, err.Error()) } resp, err := GohanDbQuery(transaction, needCommit, schemaID, sqlString, arguments) if err != nil { ThrowOttoException(&call, err.Error()) } value, _ := vm.ToValue(resp) return value }, "gohan_db_sql_make_columns": func(call otto.FunctionCall) otto.Value { VerifyCallArguments(&call, "gohan_db_query", 1) schemaID, err := GetString(call.Argument(0)) if err != nil { ThrowOttoException(&call, err.Error()) } results, err := GohanDbMakeColumns(schemaID) if err != nil { ThrowOttoException(&call, err.Error()) } value, _ := vm.ToValue(results) return value }, } for name, object := range builtins { vm.Set(name, object) } } RegisterInit(gohanDBInit) }
func init() { gohanUtilInit := func(env *Environment) { vm := env.VM builtins := map[string]interface{}{ "gohan_http": func(call otto.FunctionCall) otto.Value { if len(call.ArgumentList) == 4 { emptyOpts, _ := otto.ToValue(map[string]interface{}{}) call.ArgumentList = append(call.ArgumentList, emptyOpts) } VerifyCallArguments(&call, "gohan_http", 5) method := call.Argument(0).String() url := call.Argument(1).String() headers := ConvertOttoToGo(call.Argument(2)) data := ConvertOttoToGo(call.Argument(3)) options := ConvertOttoToGo(call.Argument(4)) log.Debug("gohan_http [%s] %s %s %s", method, headers, url, options) code, headers, body, err := gohanHTTP(method, url, headers, data, options) log.Debug("response code %d", code) resp := map[string]interface{}{} if err != nil { resp["status"] = "err" resp["error"] = err.Error() } else { resp["status"] = "success" resp["status_code"] = fmt.Sprint(code) resp["body"] = body resp["headers"] = headers } log.Debug("response code %d", code) value, _ := vm.ToValue(resp) return value }, "gohan_schemas": func(call otto.FunctionCall) otto.Value { VerifyCallArguments(&call, "gohan_schemas", 0) manager := schema.GetManager() response := []interface{}{} for _, schema := range manager.OrderedSchemas() { response = append(response, schema.RawData) } value, _ := vm.ToValue(response) return value }, "gohan_schema_url": func(call otto.FunctionCall) otto.Value { VerifyCallArguments(&call, "gohan_schema_url", 1) schemaID := call.Argument(0).String() manager := schema.GetManager() schema, ok := manager.Schema(schemaID) if !ok { ThrowOttoException(&call, unknownSchemaErrorMesssageFormat, schemaID) } value, _ := vm.ToValue(schema.URL) return value }, "gohan_policies": func(call otto.FunctionCall) otto.Value { VerifyCallArguments(&call, "gohan_policies", 0) manager := schema.GetManager() response := []interface{}{} for _, policy := range manager.Policies() { response = append(response, policy.RawData) } value, _ := vm.ToValue(response) return value }, "gohan_uuid": func(call otto.FunctionCall) otto.Value { value, _ := vm.ToValue(uuid.NewV4().String()) return value }, "gohan_sleep": func(call otto.FunctionCall) otto.Value { if len(call.ArgumentList) != 1 { panic("Wrong number of arguments in gohan_schema_url call.") } rawSleep, _ := call.Argument(0).Export() var sleep time.Duration switch rawSleep.(type) { case int: sleep = time.Duration(rawSleep.(int)) case int64: sleep = time.Duration(rawSleep.(int64)) } time.Sleep(sleep * time.Millisecond) return otto.NullValue() }, "gohan_template": func(call otto.FunctionCall) otto.Value { if len(call.ArgumentList) != 2 { panic("Wrong number of arguments in gohan_db_create call.") } rawTemplate, _ := call.Argument(0).Export() templateString, ok := rawTemplate.(string) if !ok { value, _ := vm.ToValue(rawTemplate) return value } data := ConvertOttoToGo(call.Argument(1)) t := template.Must(template.New("tmpl").Parse(templateString)) b := bytes.NewBuffer(make([]byte, 0, 100)) t.Execute(b, data) value, _ := vm.ToValue(b.String()) return value }, "gohan_exec": func(call otto.FunctionCall) otto.Value { if len(call.ArgumentList) != 2 { panic("Wrong number of arguments in gohan_db_create call.") } rawCommand, _ := call.Argument(0).Export() command, ok := rawCommand.(string) if !ok { return otto.NullValue() } stringArgs := []string{} rawArgs, _ := call.Argument(1).Export() args, ok := rawArgs.([]interface{}) if !ok { return otto.NullValue() } for _, arg := range args { stringArgs = append(stringArgs, arg.(string)) } out, err := exec.Command(command, stringArgs...).Output() resp := map[string]string{} if err != nil { resp["status"] = "error" resp["output"] = err.Error() } else { resp["status"] = "success" resp["output"] = string(out) } value, _ := vm.ToValue(resp) return value }, } for name, object := range builtins { vm.Set(name, object) } } RegistInit(gohanUtilInit) }
func init() { gohanUtilInit := func(env *Environment) { vm := env.VM builtins := map[string]interface{}{ "gohan_http": func(call otto.FunctionCall) otto.Value { if len(call.ArgumentList) == 4 { defaultOpaque, _ := otto.ToValue(false) call.ArgumentList = append(call.ArgumentList, defaultOpaque) } VerifyCallArguments(&call, "gohan_http", 5) method, err := GetString(call.Argument(0)) if err != nil { ThrowOttoException(&call, err.Error()) } url, err := GetString(call.Argument(1)) if err != nil { ThrowOttoException(&call, err.Error()) } rawHeaders, err := GetMap(call.Argument(2)) if err != nil { ThrowOttoException(&call, err.Error()) } // A string or a map[string]interface{} data := ConvertOttoToGo(call.Argument(3)) opaque, err := GetBool(call.Argument(4)) if err != nil { ThrowOttoException(&call, err.Error()) } log.Debug("gohan_http [%s] %s %s %s", method, rawHeaders, url, opaque) code, headers, body, err := gohanHTTP(method, url, rawHeaders, data, opaque) log.Debug("response code %d", code) resp := map[string]interface{}{} if err != nil { resp["status"] = "err" resp["error"] = err.Error() } else { resp["status"] = "success" resp["status_code"] = fmt.Sprint(code) resp["body"] = body resp["headers"] = headers } log.Debug("response code %d", code) value, _ := vm.ToValue(resp) return value }, "gohan_schemas": func(call otto.FunctionCall) otto.Value { VerifyCallArguments(&call, "gohan_schemas", 0) manager := schema.GetManager() response := []interface{}{} for _, schema := range manager.OrderedSchemas() { response = append(response, schema) } value, _ := vm.ToValue(response) return value }, "gohan_schema_url": func(call otto.FunctionCall) otto.Value { VerifyCallArguments(&call, "gohan_schema_url", 1) schemaID, err := GetString(call.Argument(0)) if err != nil { ThrowOttoException(&call, err.Error()) } schema, err := getSchema(schemaID) if err != nil { ThrowOttoException(&call, err.Error()) } value, _ := vm.ToValue(schema.URL) return value }, "gohan_policies": func(call otto.FunctionCall) otto.Value { VerifyCallArguments(&call, "gohan_policies", 0) manager := schema.GetManager() response := []interface{}{} for _, policy := range manager.Policies() { response = append(response, policy.RawData) } value, _ := vm.ToValue(response) return value }, "gohan_uuid": func(call otto.FunctionCall) otto.Value { value, _ := vm.ToValue(uuid.NewV4().String()) return value }, "gohan_sleep": func(call otto.FunctionCall) otto.Value { VerifyCallArguments(&call, "gohan_sleep", 1) rawSleep, _ := call.Argument(0).Export() var sleep time.Duration switch rawSleep.(type) { case int: sleep = time.Duration(rawSleep.(int)) case int64: sleep = time.Duration(rawSleep.(int64)) } time.Sleep(sleep * time.Millisecond) return otto.NullValue() }, "gohan_template": func(call otto.FunctionCall) otto.Value { VerifyCallArguments(&call, "gohan_template", 2) templateString, err := GetString(call.Argument(0)) if err != nil { return call.Argument(0) } data := ConvertOttoToGo(call.Argument(1)) t := template.Must(template.New("tmpl").Parse(templateString)) b := bytes.NewBuffer(make([]byte, 0, 100)) t.Execute(b, data) value, _ := vm.ToValue(b.String()) return value }, "gohan_exec": func(call otto.FunctionCall) otto.Value { VerifyCallArguments(&call, "gohan_exec", 2) command, err := GetString(call.Argument(0)) if err != nil { ThrowOttoException(&call, err.Error()) } stringArgs, err := GetStringList(call.Argument(1)) if err != nil { ThrowOttoException(&call, err.Error()) } out, err := exec.Command(command, stringArgs...).Output() resp := map[string]string{} if err != nil { resp["status"] = "error" resp["output"] = err.Error() } else { resp["status"] = "success" resp["output"] = string(out) } value, _ := vm.ToValue(resp) return value }, "gohan_config": func(call otto.FunctionCall) otto.Value { VerifyCallArguments(&call, "gohan_exec", 2) configKey, err := GetString(call.Argument(0)) if err != nil { ThrowOttoException(&call, err.Error()) } defaultValue, err := call.Argument(1).Export() if err != nil { ThrowOttoException(&call, err.Error()) } config := util.GetConfig() result := config.GetParam(configKey, defaultValue) value, _ := vm.ToValue(result) return value }, } for name, object := range builtins { vm.Set(name, object) } } RegisterInit(gohanUtilInit) }