示例#1
0
文件: utils.go 项目: vindalu/vindalu
// 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
}