// Build elasticsearch query from vindalu query func buildElasticsearchBaseQuery(index string, req map[string]interface{}) (query map[string]interface{}, err error) { filterOps := []interface{}{} for k, v := range req { switch v.(type) { case string: val, _ := v.(string) val = strings.TrimSpace(val) if strings.HasPrefix(val, ">") || strings.HasPrefix(val, "<") { // Parse number aVal := "" if strings.HasPrefix(val, ">=") || strings.HasPrefix(val, "<=") { aVal = strings.TrimSpace(val[2:]) } else { aVal = strings.TrimSpace(val[1:]) } // Parse number for comparison var nVal interface{} nVal, ierr := strconv.ParseInt(aVal, 10, 64) if ierr != nil { ierr = nil if nVal, ierr = strconv.ParseFloat(aVal, 64); ierr != nil { err = ierr return } } // Add range filterop if strings.HasPrefix(val, ">") { filterOps = append(filterOps, elastigo.Range().Field(k).Gt(nVal)) } else { filterOps = append(filterOps, elastigo.Range().Field(k).Lt(nVal)) } } else { if isRegexSearch(val) { filterOps = append(filterOps, regexFilter(k, val)) } else { filterOps = append(filterOps, map[string]interface{}{ "term": map[string]string{k: val}, }) } } break case int: break case int64: break case float64: break case []interface{}: break case interface{}: break default: err = fmt.Errorf("invalid type: %#v", v) return } } if len(filterOps) > 0 { query = map[string]interface{}{ "query": map[string]interface{}{ "filtered": elastigo.Search(index).Filter(filterOps...), }, } } else { // Empty query i.e. return everything query = map[string]interface{}{} } return }
/* { "type": ["virtualserver", "physicalserver"], "os": "ubuntu" } */ func (ir *Inventory) parseRequestBody(r *http.Request) (query interface{}, err error) { // check happens earlier var body []byte if body, err = ioutil.ReadAll(r.Body); err != nil { return } defer r.Body.Close() var req map[string]interface{} if err = json.Unmarshal(body, &req); err != nil { return } filterOps := []interface{}{} for k, v := range req { switch v.(type) { case string: val, _ := v.(string) val = strings.TrimSpace(val) if strings.HasPrefix(val, ">") || strings.HasPrefix(val, "<") { // Parse number aVal := "" if strings.HasPrefix(val, ">=") || strings.HasPrefix(val, "<=") { aVal = strings.TrimSpace(val[2:]) } else { aVal = strings.TrimSpace(val[1:]) } // Parse number for comparison var nVal interface{} nVal, ierr := strconv.ParseInt(aVal, 10, 64) if ierr != nil { ierr = nil if nVal, ierr = strconv.ParseFloat(aVal, 64); ierr != nil { err = ierr return } } // Add range filterop if strings.HasPrefix(val, ">") { filterOps = append(filterOps, elastigo.Range().Field(k).Gt(nVal)) } else { filterOps = append(filterOps, elastigo.Range().Field(k).Lt(nVal)) } } else { filterOps = append(filterOps, elastigo.Filter().Terms(k, val)) } break case int: //val, _ := v.(int) break case int64: //val, _ := v.(int64) break case float64: //val, _ := v.(float64) break case []interface{}: vals, _ := v.([]interface{}) filterOps = append(filterOps, elastigo.Filter().Terms(k, vals...)) break case interface{}: //val, _ := v.(interface{}) break default: err = fmt.Errorf("invalid type: %#v", v) return } } query = elastigo.Search(ir.cfg.Datastore.Config.Index).Filter(filterOps...) return }