diff --git a/api/api.go b/api/api.go index 35d2619e..650222ce 100644 --- a/api/api.go +++ b/api/api.go @@ -280,24 +280,22 @@ func GetUser(w http.ResponseWriter, r *http.Request) { } } -// SubmitPlan insert a new Terraform plan in the database. +// SubmitPlan inserts a new Terraform plan in the database. // /api/plans POST endpoint callback func SubmitPlan(w http.ResponseWriter, r *http.Request, db *db.Database) { - if r.Method == "POST" { - w.Header().Set("Access-Control-Allow-Origin", "*") + w.Header().Set("Access-Control-Allow-Origin", "*") - body, err := ioutil.ReadAll(r.Body) - if err != nil { - log.Errorf("Failed to read body: %v", err) - JSONError(w, "Failed to read body during plan submit", err) - return - } + body, err := ioutil.ReadAll(r.Body) + if err != nil { + log.Errorf("Failed to read body: %v", err) + JSONError(w, "Failed to read body during plan submit", err) + return + } - if err = db.InsertPlan(body); err != nil { - log.Errorf("Failed to insert plan to db: %v", err) - JSONError(w, "Failed to insert plan to db", err) - return - } + if err = db.InsertPlan(body); err != nil { + log.Errorf("Failed to insert plan to db: %v", err) + JSONError(w, "Failed to insert plan to db", err) + return } } @@ -306,20 +304,30 @@ func SubmitPlan(w http.ResponseWriter, r *http.Request, db *db.Database) { // Sorted by most recent to oldest. // /api/plans GET endpoint callback func GetPlans(w http.ResponseWriter, r *http.Request, db *db.Database) { - if r.Method == "GET" { - w.Header().Set("Access-Control-Allow-Origin", "*") - lineage := r.URL.Query().Get("lineage") - limit := r.URL.Query().Get("limit") - plans := db.GetPlans(lineage, limit) + w.Header().Set("Access-Control-Allow-Origin", "*") + lineage := r.URL.Query().Get("lineage") + limit := r.URL.Query().Get("limit") + plans := db.GetPlans(lineage, limit) - j, err := json.Marshal(plans) - if err != nil { - log.Errorf("Failed to marshal plans: %v", err) - JSONError(w, "Failed to marshal plans", err) - return - } - if _, err := io.WriteString(w, string(j)); err != nil { - log.Error(err.Error()) - } + j, err := json.Marshal(plans) + if err != nil { + log.Errorf("Failed to marshal plans: %v", err) + JSONError(w, "Failed to marshal plans", err) + return + } + if _, err := io.WriteString(w, string(j)); err != nil { + log.Error(err.Error()) + } +} + +// ManagePlans is used to route the request to the appropriated handler function +// on /api/plans request +func ManagePlans(w http.ResponseWriter, r *http.Request, db *db.Database) { + if r.Method == "GET" { + GetPlans(w, r, db) + } else if r.Method == "POST" { + SubmitPlan(w, r, db) + } else { + http.Error(w, "Invalid request method.", 405) } } diff --git a/db/db.go b/db/db.go index f9539bc9..0e6a8e2a 100644 --- a/db/db.go +++ b/db/db.go @@ -567,15 +567,15 @@ func (db *Database) ListAttributeKeys(resourceType string) (results []string, er // InsertPlan inserts a Terraform plan with associated information in the Database func (db *Database) InsertPlan(plan []byte) error { - // Check for lineage existence var lineage types.Lineage if err := json.Unmarshal(plan, &lineage); err != nil { return err } - res := db.First(&lineage, lineage) - if errors.Is(res.Error, gorm.ErrRecordNotFound) { - return fmt.Errorf("Plan's lineage not found in db") + // Recover lineage from db if it's already exists or insert it + res := db.FirstOrCreate(&lineage, lineage) + if res.Error != nil { + return fmt.Errorf("Error on lineage retrival during plan insertion: %v", res.Error) } var p types.Plan diff --git a/main.go b/main.go index 25ccfe45..1d10406b 100644 --- a/main.go +++ b/main.go @@ -196,15 +196,7 @@ func main() { http.HandleFunc(util.GetFullPath("api/resource/names"), handleWithDB(api.ListResourceNames, database)) http.HandleFunc(util.GetFullPath("api/attribute/keys"), handleWithDB(api.ListAttributeKeys, database)) http.HandleFunc(util.GetFullPath("api/tf_versions"), handleWithDB(api.ListTfVersions, database)) - http.HandleFunc(util.GetFullPath("api/plans"), func(w http.ResponseWriter, r *http.Request) { - if r.Method == "GET" { - api.GetPlans(w, r, database) - } else if r.Method == "POST" { - api.SubmitPlan(w, r, database) - } else { - http.Error(w, "Invalid request method.", 405) - } - }) + http.HandleFunc(util.GetFullPath("api/plans"), handleWithDB(api.ManagePlans, database)) // Start server log.Debugf("Listening on port %d\n", c.Web.Port)