terraform/vendor/github.com/go-chef/chef/search.go

149 lines
4.0 KiB
Go

package chef
import (
"errors"
"fmt"
"strings"
)
type SearchService struct {
client *Client
}
// SearchQuery Is the struct for holding a query request
type SearchQuery struct {
// The index you want to search
Index string
// The query you want to execute. This is the 'chef' query ex: 'chef_environment:prod'
Query string
// Sort order you want the search results returned
SortBy string
// Starting position for search
Start int
// Number of rows to return
Rows int
}
// String implements the Stringer Interface for the SearchQuery
func (q SearchQuery) String() string {
return fmt.Sprintf("%s?q=%s&rows=%d&sort=%s&start=%d", q.Index, q.Query, q.Rows, q.SortBy, q.Start)
}
// SearchResult will return a slice of interface{} of chef-like objects (roles/nodes/etc)
type SearchResult struct {
Total int
Start int
Rows []interface{}
}
// Do will execute the search query on the client
func (q SearchQuery) Do(client *Client) (res SearchResult, err error) {
fullUrl := fmt.Sprintf("search/%s", q)
err = client.magicRequestDecoder("GET", fullUrl, nil, &res)
return
}
// DoPartial will execute the search query on the client with partal mapping
func (q SearchQuery) DoPartial(client *Client, params map[string]interface{}) (res SearchResult, err error) {
fullUrl := fmt.Sprintf("search/%s", q)
body, err := JSONReader(params)
if err != nil {
debug("Problem encoding params for body", err.Error())
return
}
err = client.magicRequestDecoder("POST", fullUrl, body, &res)
return
}
// NewSearch is a constructor for a SearchQuery struct. This is used by other search service methods to perform search requests on the server
func (e SearchService) NewQuery(idx, statement string) (query SearchQuery, err error) {
// validate statement
if !strings.Contains(statement, ":") {
err = errors.New("statement is malformed")
return
}
query = SearchQuery{
Index: idx,
Query: statement,
// These are the defaults in chef: https://github.com/opscode/chef/blob/master/lib/chef/search/query.rb#L102-L105
SortBy: "X_CHEF_id_CHEF_X asc",
Start: 0,
Rows: 1000,
}
return
}
// Exec runs the query on the index passed in. This is a helper method. If you want more controll over the query use NewQuery and its Do() method.
// BUG(spheromak): Should we use exec or SearchQuery.Do() or have both ?
func (e SearchService) Exec(idx, statement string) (res SearchResult, err error) {
// Copy-paste here till We decide which way to go with exec vs Do
if !strings.Contains(statement, ":") {
err = errors.New("statement is malformed")
return
}
query := SearchQuery{
Index: idx,
Query: statement,
// These are the defaults in chef: https://github.com/opscode/chef/blob/master/lib/chef/search/query.rb#L102-L105
SortBy: "X_CHEF_id_CHEF_X asc",
Start: 0,
Rows: 1000,
}
res, err = query.Do(e.client)
start := res.Start
inc := 1000
total := res.Total
for start + inc <= total {
query.Start = query.Start + 1000
start = query.Start
ares, err := query.Do(e.client)
if err != nil {
return res, err
}
res.Rows = append(res.Rows, ares.Rows...)
}
return
}
// PartialExec Executes a partial search based on passed in params and the query.
func (e SearchService) PartialExec(idx, statement string, params map[string]interface{}) (res SearchResult, err error) {
query := SearchQuery{
Index: idx,
Query: statement,
// These are the defaults in chef: https://github.com/opscode/chef/blob/master/lib/chef/search/query.rb#L102-L105
SortBy: "X_CHEF_id_CHEF_X asc",
Start: 0,
Rows: 1000,
}
fullUrl := fmt.Sprintf("search/%s", query)
body, err := JSONReader(params)
if err != nil {
debug("Problem encoding params for body")
return
}
err = e.client.magicRequestDecoder("POST", fullUrl, body, &res)
return
}
// List lists the nodes in the Chef server.
//
// Chef API docs: http://docs.opscode.com/api_chef_server.html#id25
func (e SearchService) Indexes() (data map[string]string, err error) {
err = e.client.magicRequestDecoder("GET", "search", nil, &data)
return
}