package operations import ( "context" "fmt" "strings" "sync" "github.com/direktiv/apps/go/pkg/apps" "github.com/go-openapi/runtime/middleware" "github.com/go-openapi/strfmt" "app/models" ) const ( successKey = "success" resultKey = "result" // http related statusKey = "status" codeKey = "code" headersKey = "headers" ) var sm sync.Map const ( cmdErr = "io.direktiv.command.error" outErr = "io.direktiv.output.error" riErr = "io.direktiv.ri.error" ) type accParams struct { PostParams Commands []interface{} DirektivDir string } type accParamsTemplate struct { models.PostParamsBody Commands []interface{} DirektivDir string } type ctxInfo struct { cf context.CancelFunc cancelled bool } func PostDirektivHandle(params PostParams) middleware.Responder { resp := &models.PostOKBody{} var ( err error ret interface{} cont bool ) ri, err := apps.RequestinfoFromRequest(params.HTTPRequest) if err != nil { return generateError(riErr, err) } ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) sm.Store(*params.DirektivActionID, &ctxInfo{ cancel, false, }) defer sm.Delete(*params.DirektivActionID) var responses []interface{} var paramsCollector []interface{} accParams := accParams{ params, nil, ri.Dir(), } ret, err = runCommand0(ctx, accParams, ri) responses = append(responses, ret) // if foreach returns an error there is no continue // // default we do not continue cont = convertTemplateToBool("", accParams, false) // cont = convertTemplateToBool("", accParams, true) // if err != nil && !cont { errName := cmdErr // if the delete function added the cancel tag ci, ok := sm.Load(*params.DirektivActionID) if ok { cinfo, ok := ci.(*ctxInfo) if ok && cinfo.cancelled { errName = "direktiv.actionCancelled" err = fmt.Errorf("action got cancel request") } } return generateError(errName, err) } paramsCollector = append(paramsCollector, ret) accParams.Commands = paramsCollector ret, err = runCommand1(ctx, accParams, ri) responses = append(responses, ret) // if foreach returns an error there is no continue // // default we do not continue cont = convertTemplateToBool("", accParams, false) // cont = convertTemplateToBool("", accParams, true) // if err != nil && !cont { errName := cmdErr // if the delete function added the cancel tag ci, ok := sm.Load(*params.DirektivActionID) if ok { cinfo, ok := ci.(*ctxInfo) if ok && cinfo.cancelled { errName = "direktiv.actionCancelled" err = fmt.Errorf("action got cancel request") } } return generateError(errName, err) } paramsCollector = append(paramsCollector, ret) accParams.Commands = paramsCollector s, err := templateString(`{ "export-excel": {{ (index . 1).result | toJson }} } `, responses) if err != nil { return generateError(outErr, err) } responseBytes := []byte(s) // validate resp.UnmarshalBinary(responseBytes) err = resp.Validate(strfmt.Default) if err != nil { return generateError(outErr, err) } return NewPostOK().WithPayload(resp) } // exec func runCommand0(ctx context.Context, params accParams, ri *apps.RequestInfo) (map[string]interface{}, error) { ir := make(map[string]interface{}) ir[successKey] = false at := accParamsTemplate{ *params.Body, params.Commands, params.DirektivDir, } cmd, err := templateString(`/bin/json2excel -inputJson {{- if eq (deref .Infile) "" }} "/tmp/input.json" {{- else }} {{ .Infile }} {{- end }} input.json -worksheetName "{{ .WorksheetName }}" -outputFilename '{{ .OutFilename }}'`, at) if err != nil { ri.Logger().Infof("error executing command: %v", err) ir[resultKey] = err.Error() return ir, err } cmd = strings.Replace(cmd, "\n", "", -1) silent := convertTemplateToBool("false", at, false) print := convertTemplateToBool("true", at, true) output := "" envs := []string{} return runCmd(ctx, cmd, envs, output, silent, print, ri) } // end commands // exec func runCommand1(ctx context.Context, params accParams, ri *apps.RequestInfo) (map[string]interface{}, error) { ir := make(map[string]interface{}) ir[successKey] = false at := accParamsTemplate{ *params.Body, params.Commands, params.DirektivDir, } cmd, err := templateString(`base64 -w 0 /tmp/{{ .OutFilename }}`, at) if err != nil { ri.Logger().Infof("error executing command: %v", err) ir[resultKey] = err.Error() return ir, err } cmd = strings.Replace(cmd, "\n", "", -1) silent := convertTemplateToBool("", at, false) print := convertTemplateToBool("", at, true) output := "" envs := []string{} return runCmd(ctx, cmd, envs, output, silent, print, ri) } // end commands func generateError(code string, err error) *PostDefault { d := NewPostDefault(0).WithDirektivErrorCode(code). WithDirektivErrorMessage(err.Error()) errString := err.Error() errResp := models.Error{ ErrorCode: &code, ErrorMessage: &errString, } d.SetPayload(&errResp) return d } func HandleShutdown() { // nothing for generated functions }