func formatFile(filename string, write, backup bool) error { data, err := readFile(filename) if err != nil { return err } formatted, err := tick.Format(data) if err != nil { return err } if write { dir := filepath.Dir(filename) tmp, err := writeTmpFile(dir, formatted) if err != nil { return err } defer os.Remove(tmp) if backup { err := os.Rename(filename, filename+backupExt) if err != nil { return err } } err = os.Rename(tmp, filename) if err != nil { return err } } else { _, err := os.Stdout.Write([]byte(formatted)) if err != nil { return err } } return nil }
func (ts *Service) convertTemplate(t Template, scriptFormat string) (client.Template, error) { script := t.TICKscript if scriptFormat == "formatted" { // Format TICKscript formatted, err := tick.Format(script) if err == nil { // Only format if it succeeded. // Otherwise a change in syntax may prevent task retrieval. script = formatted } } errMsg := t.Error task, err := ts.templateTask(t) if err != nil { errMsg = err.Error() } var typ client.TaskType switch t.Type { case StreamTask: typ = client.StreamTask case BatchTask: typ = client.BatchTask default: return client.Template{}, fmt.Errorf("invalid task type %v", t.Type) } vars, err := ts.convertToClientVarsFromTick(task.Vars()) if err != nil { return client.Template{}, err } return client.Template{ Link: ts.templateLink(t.ID), ID: t.ID, Type: typ, TICKscript: script, Dot: string(task.Dot()), Error: errMsg, Created: t.Created, Modified: t.Modified, Vars: vars, }, nil }
func (ts *Service) convertTask(t Task, scriptFormat, dotView string, tm *kapacitor.TaskMaster) (client.Task, error) { script := t.TICKscript if scriptFormat == "formatted" { // Format TICKscript formatted, err := tick.Format(script) if err == nil { // Only format if it succeeded. // Otherwise a change in syntax may prevent task retrieval. script = formatted } } executing := tm.IsExecuting(t.ID) errMsg := t.Error dot := "" stats := client.ExecutionStats{} task, err := ts.newKapacitorTask(t) if err == nil { if executing { dot = tm.ExecutingDot(t.ID, dotView == "labels") s, err := tm.ExecutionStats(t.ID) if err != nil { ts.logger.Printf("E! failed to retrieve stats for task %s: %v", t.ID, err) } else { stats.TaskStats = s.TaskStats stats.NodeStats = s.NodeStats } } else { dot = string(task.Dot()) } } else { errMsg = err.Error() } var status client.TaskStatus switch t.Status { case Disabled: status = client.Disabled case Enabled: status = client.Enabled default: return client.Task{}, fmt.Errorf("invalid task status %v", t.Status) } var typ client.TaskType switch t.Type { case StreamTask: typ = client.StreamTask case BatchTask: typ = client.BatchTask default: return client.Task{}, fmt.Errorf("invalid task type %v", t.Type) } dbrps := make([]client.DBRP, len(t.DBRPs)) for i, dbrp := range t.DBRPs { dbrps[i] = client.DBRP{ Database: dbrp.Database, RetentionPolicy: dbrp.RetentionPolicy, } } vars, err := ts.convertToClientVars(t.Vars) if err != nil { return client.Task{}, err } return client.Task{ Link: ts.taskLink(t.ID), ID: t.ID, TemplateID: t.TemplateID, Type: typ, DBRPs: dbrps, TICKscript: script, Vars: vars, Status: status, Dot: dot, Executing: executing, ExecutionStats: stats, Created: t.Created, Modified: t.Modified, LastEnabled: t.LastEnabled, Error: errMsg, }, nil }
func (ts *Service) handleListTasks(w http.ResponseWriter, r *http.Request) { pattern := r.URL.Query().Get("pattern") fields := r.URL.Query()["fields"] if len(fields) == 0 { fields = allTaskFields } else { // Always return ID field fields = append(fields, "id", "link") } scriptFormat := r.URL.Query().Get("script-format") switch scriptFormat { case "": scriptFormat = "formatted" case "formatted": case "raw": default: httpd.HttpError(w, fmt.Sprintf("invalid script-format parameter %q", scriptFormat), true, http.StatusBadRequest) return } dotView := r.URL.Query().Get("dot-view") switch dotView { case "": dotView = "attributes" case "attributes": case "labels": default: httpd.HttpError(w, fmt.Sprintf("invalid dot-view parameter %q", dotView), true, http.StatusBadRequest) return } var err error offset := int64(0) offsetStr := r.URL.Query().Get("offset") if offsetStr != "" { offset, err = strconv.ParseInt(offsetStr, 10, 64) if err != nil { httpd.HttpError(w, fmt.Sprintf("invalid offset parameter %q must be an integer: %s", offsetStr, err), true, http.StatusBadRequest) } } limit := int64(100) limitStr := r.URL.Query().Get("limit") if limitStr != "" { limit, err = strconv.ParseInt(limitStr, 10, 64) if err != nil { httpd.HttpError(w, fmt.Sprintf("invalid limit parameter %q must be an integer: %s", limitStr, err), true, http.StatusBadRequest) } } rawTasks, err := ts.tasks.List(pattern, int(offset), int(limit)) tasks := make([]map[string]interface{}, len(rawTasks)) tm := ts.TaskMasterLookup.Main() for i, task := range rawTasks { tasks[i] = make(map[string]interface{}, len(fields)) executing := tm.IsExecuting(task.ID) for _, field := range fields { var value interface{} switch field { case "id": value = task.ID case "link": value = ts.taskLink(task.ID) case "type": switch task.Type { case StreamTask: value = client.StreamTask case BatchTask: value = client.BatchTask } case "dbrps": dbrps := make([]client.DBRP, len(task.DBRPs)) for i, dbrp := range task.DBRPs { dbrps[i] = client.DBRP{ Database: dbrp.Database, RetentionPolicy: dbrp.RetentionPolicy, } } value = dbrps case "script": value = task.TICKscript if scriptFormat == "formatted" { formatted, err := tick.Format(task.TICKscript) if err == nil { // Only format if it succeeded. // Otherwise a change in syntax may prevent task retrieval. value = formatted } } case "executing": value = executing case "dot": if executing { value = tm.ExecutingDot(task.ID, dotView == "labels") } else { kt, err := ts.newKapacitorTask(task) if err != nil { break } value = string(kt.Dot()) } case "stats": if executing { s, err := tm.ExecutionStats(task.ID) if err != nil { ts.logger.Printf("E! failed to retrieve stats for task %s: %v", task.ID, err) } else { value = client.ExecutionStats{ TaskStats: s.TaskStats, NodeStats: s.NodeStats, } } } case "error": value = task.Error case "status": switch task.Status { case Disabled: value = client.Disabled case Enabled: value = client.Enabled } case "created": value = task.Created case "modified": value = task.Modified case "last-enabled": value = task.LastEnabled default: httpd.HttpError(w, fmt.Sprintf("unsupported field %q", field), true, http.StatusBadRequest) return } tasks[i][field] = value } } type response struct { Tasks []map[string]interface{} `json:"tasks"` } w.Write(httpd.MarshalJSON(response{tasks}, true)) }
func (ts *Service) handleListTemplates(w http.ResponseWriter, r *http.Request) { pattern := r.URL.Query().Get("pattern") fields := r.URL.Query()["fields"] if len(fields) == 0 { fields = allTemplateFields } else { // Always return ID field fields = append(fields, "id", "link") } scriptFormat := r.URL.Query().Get("script-format") switch scriptFormat { case "": scriptFormat = "formatted" case "formatted": case "raw": default: httpd.HttpError(w, fmt.Sprintf("invalid script-format parameter %q", scriptFormat), true, http.StatusBadRequest) return } var err error offset := int64(0) offsetStr := r.URL.Query().Get("offset") if offsetStr != "" { offset, err = strconv.ParseInt(offsetStr, 10, 64) if err != nil { httpd.HttpError(w, fmt.Sprintf("invalid offset parameter %q must be an integer: %s", offsetStr, err), true, http.StatusBadRequest) } } limit := int64(100) limitStr := r.URL.Query().Get("limit") if limitStr != "" { limit, err = strconv.ParseInt(limitStr, 10, 64) if err != nil { httpd.HttpError(w, fmt.Sprintf("invalid limit parameter %q must be an integer: %s", limitStr, err), true, http.StatusBadRequest) } } rawTemplates, err := ts.templates.List(pattern, int(offset), int(limit)) templates := make([]map[string]interface{}, len(rawTemplates)) for i, template := range rawTemplates { templates[i] = make(map[string]interface{}, len(fields)) task, err := ts.templateTask(template) if err != nil { continue } for _, field := range fields { var value interface{} switch field { case "id": value = template.ID case "link": value = ts.templateLink(template.ID) case "type": switch template.Type { case StreamTask: value = client.StreamTask case BatchTask: value = client.BatchTask } case "script": value = template.TICKscript if scriptFormat == "formatted" { formatted, err := tick.Format(template.TICKscript) if err == nil { // Only format if it succeeded. // Otherwise a change in syntax may prevent template retrieval. value = formatted } } case "dot": value = string(task.Dot()) case "vars": vars, err := ts.convertToClientVarsFromTick(task.Vars()) if err != nil { ts.logger.Printf("E! failed to get vars for template %s: %s", template.ID, err) break } value = vars case "error": value = template.Error case "created": value = template.Created case "modified": value = template.Modified default: httpd.HttpError(w, fmt.Sprintf("unsupported field %q", field), true, http.StatusBadRequest) return } templates[i][field] = value } } type response struct { Templates []map[string]interface{} `json:"templates"` } w.Write(httpd.MarshalJSON(response{templates}, true)) }