Implement clients for labels, packs and queries (#1760)

Go client methods for making get, set and delete requests on label, pack and
query entities.
This commit is contained in:
Zachary Wasserman 2018-05-07 12:44:40 -07:00 committed by GitHub
parent 8febf3ed96
commit 3d1d088be9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 283 additions and 12 deletions

View file

@ -26,7 +26,7 @@ func NewClient(addr string, insecureSkipVerify bool) (*Client, error) {
baseURL, err := url.Parse(addr)
if err != nil {
return nil, errors.Wrap(err, "error parsing URL")
return nil, errors.Wrap(err, "parsing URL")
}
httpClient := &http.Client{
@ -43,18 +43,22 @@ func NewClient(addr string, insecureSkipVerify bool) (*Client, error) {
}
func (c *Client) doWithHeaders(verb, path string, params interface{}, headers map[string]string) (*http.Response, error) {
b, err := json.Marshal(params)
if err != nil {
return nil, errors.Wrap(err, "error marshaling json")
var bodyBytes []byte
var err error
if params != nil {
bodyBytes, err = json.Marshal(params)
if err != nil {
return nil, errors.Wrap(err, "marshaling json")
}
}
request, err := http.NewRequest(
verb,
c.url(path).String(),
bytes.NewBuffer(b),
bytes.NewBuffer(bodyBytes),
)
if err != nil {
return nil, errors.Wrap(err, "error creating request object")
return nil, errors.Wrap(err, "creating request object")
}
for k, v := range headers {
request.Header.Set(k, v)

View file

@ -0,0 +1,89 @@
package service
import (
"encoding/json"
"net/http"
"net/url"
"github.com/kolide/fleet/server/kolide"
"github.com/pkg/errors"
)
// ApplyLabelSpecs sends the list of Labels to be applied (upserted) to the
// Fleet instance.
func (c *Client) ApplyLabelSpecs(specs []*kolide.LabelSpec) error {
req := applyLabelSpecsRequest{Specs: specs}
response, err := c.Do("POST", "/api/v1/kolide/spec/labels", req)
if err != nil {
return errors.Wrap(err, "POST /api/v1/kolide/spec/labels")
}
defer response.Body.Close()
if response.StatusCode != http.StatusOK {
return errors.Errorf("apply label spec got HTTP %d, expected 200", response.StatusCode)
}
var responseBody applyLabelSpecsResponse
err = json.NewDecoder(response.Body).Decode(&responseBody)
if err != nil {
return errors.Wrap(err, "decode apply label spec response")
}
if responseBody.Err != nil {
return errors.Errorf("apply label spec: %s", responseBody.Err)
}
return nil
}
// GetLabelSpecs retrieves the list of all Labels.
func (c *Client) GetLabelSpecs(specs []*kolide.LabelSpec) ([]*kolide.LabelSpec, error) {
req := applyLabelSpecsRequest{Specs: specs}
response, err := c.Do("GET", "/api/v1/kolide/spec/labels", req)
if err != nil {
return nil, errors.Wrap(err, "GET /api/v1/kolide/spec/labels")
}
defer response.Body.Close()
if response.StatusCode != http.StatusOK {
return nil, errors.Errorf("get label spec got HTTP %d, expected 200", response.StatusCode)
}
var responseBody getLabelSpecsResponse
err = json.NewDecoder(response.Body).Decode(&responseBody)
if err != nil {
return nil, errors.Wrap(err, "decode get label spec response")
}
if responseBody.Err != nil {
return nil, errors.Errorf("get label spec: %s", responseBody.Err)
}
return responseBody.Specs, nil
}
// DeleteLabel deletes the label with the matching name.
func (c *Client) DeleteLabel(name string) error {
verb, path := "DELETE", "/api/v1/kolide/labels/"+url.QueryEscape(name)
response, err := c.Do(verb, path, nil)
if err != nil {
return errors.Wrapf(err, "%s %s", verb, path)
}
defer response.Body.Close()
if response.StatusCode != http.StatusOK {
return errors.Errorf("get label spec got HTTP %d, expected 200", response.StatusCode)
}
var responseBody deleteLabelResponse
err = json.NewDecoder(response.Body).Decode(&responseBody)
if err != nil {
return errors.Wrap(err, "decode get label spec response")
}
if responseBody.Err != nil {
return errors.Errorf("get label spec: %s", responseBody.Err)
}
return nil
}

View file

@ -0,0 +1,89 @@
package service
import (
"encoding/json"
"net/http"
"net/url"
"github.com/kolide/fleet/server/kolide"
"github.com/pkg/errors"
)
// ApplyPackSpecs sends the list of Packs to be applied (upserted) to the
// Fleet instance.
func (c *Client) ApplyPackSpecs(specs []*kolide.PackSpec) error {
req := applyPackSpecsRequest{Specs: specs}
response, err := c.Do("POST", "/api/v1/kolide/spec/packs", req)
if err != nil {
return errors.Wrap(err, "POST /api/v1/kolide/spec/packs")
}
defer response.Body.Close()
if response.StatusCode != http.StatusOK {
return errors.Errorf("apply pack spec got HTTP %d, expected 200", response.StatusCode)
}
var responseBody applyPackSpecsResponse
err = json.NewDecoder(response.Body).Decode(&responseBody)
if err != nil {
return errors.Wrap(err, "decode apply pack spec response")
}
if responseBody.Err != nil {
return errors.Errorf("apply pack spec: %s", responseBody.Err)
}
return nil
}
// GetPackSpecs retrieves the list of all Packs.
func (c *Client) GetPackSpecs(specs []*kolide.PackSpec) ([]*kolide.PackSpec, error) {
req := applyPackSpecsRequest{Specs: specs}
response, err := c.Do("GET", "/api/v1/kolide/spec/packs", req)
if err != nil {
return nil, errors.Wrap(err, "GET /api/v1/kolide/spec/packs")
}
defer response.Body.Close()
if response.StatusCode != http.StatusOK {
return nil, errors.Errorf("get pack spec got HTTP %d, expected 200", response.StatusCode)
}
var responseBody getPackSpecsResponse
err = json.NewDecoder(response.Body).Decode(&responseBody)
if err != nil {
return nil, errors.Wrap(err, "decode get pack spec response")
}
if responseBody.Err != nil {
return nil, errors.Errorf("get pack spec: %s", responseBody.Err)
}
return responseBody.Specs, nil
}
// DeletePack deletes the pack with the matching name.
func (c *Client) DeletePack(name string) error {
verb, path := "DELETE", "/api/v1/kolide/packs/"+url.QueryEscape(name)
response, err := c.Do(verb, path, nil)
if err != nil {
return errors.Wrapf(err, "%s %s", verb, path)
}
defer response.Body.Close()
if response.StatusCode != http.StatusOK {
return errors.Errorf("get pack spec got HTTP %d, expected 200", response.StatusCode)
}
var responseBody deletePackResponse
err = json.NewDecoder(response.Body).Decode(&responseBody)
if err != nil {
return errors.Wrap(err, "decode get pack spec response")
}
if responseBody.Err != nil {
return errors.Errorf("get pack spec: %s", responseBody.Err)
}
return nil
}

View file

@ -0,0 +1,89 @@
package service
import (
"encoding/json"
"net/http"
"net/url"
"github.com/kolide/fleet/server/kolide"
"github.com/pkg/errors"
)
// ApplyQuerySpecs sends the list of Queries to be applied (upserted) to the
// Fleet instance.
func (c *Client) ApplyQuerySpecs(specs []*kolide.QuerySpec) error {
req := applyQuerySpecsRequest{Specs: specs}
response, err := c.Do("POST", "/api/v1/kolide/spec/queries", req)
if err != nil {
return errors.Wrap(err, "POST /api/v1/kolide/spec/queries")
}
defer response.Body.Close()
if response.StatusCode != http.StatusOK {
return errors.Errorf("apply query spec got HTTP %d, expected 200", response.StatusCode)
}
var responseBody applyQuerySpecsResponse
err = json.NewDecoder(response.Body).Decode(&responseBody)
if err != nil {
return errors.Wrap(err, "decode apply query spec response")
}
if responseBody.Err != nil {
return errors.Errorf("apply query spec: %s", responseBody.Err)
}
return nil
}
// GetQuerySpecs retrieves the list of all Queries.
func (c *Client) GetQuerySpecs(specs []*kolide.QuerySpec) ([]*kolide.QuerySpec, error) {
req := applyQuerySpecsRequest{Specs: specs}
response, err := c.Do("GET", "/api/v1/kolide/spec/queries", req)
if err != nil {
return nil, errors.Wrap(err, "GET /api/v1/kolide/spec/queries")
}
defer response.Body.Close()
if response.StatusCode != http.StatusOK {
return nil, errors.Errorf("get query spec got HTTP %d, expected 200", response.StatusCode)
}
var responseBody getQuerySpecsResponse
err = json.NewDecoder(response.Body).Decode(&responseBody)
if err != nil {
return nil, errors.Wrap(err, "decode get query spec response")
}
if responseBody.Err != nil {
return nil, errors.Errorf("get query spec: %s", responseBody.Err)
}
return responseBody.Specs, nil
}
// DeleteQuery deletes the query with the matching name.
func (c *Client) DeleteQuery(name string) error {
verb, path := "DELETE", "/api/v1/kolide/queries/"+url.QueryEscape(name)
response, err := c.Do(verb, path, nil)
if err != nil {
return errors.Wrapf(err, "%s %s", verb, path)
}
defer response.Body.Close()
if response.StatusCode != http.StatusOK {
return errors.Errorf("get query spec got HTTP %d, expected 200", response.StatusCode)
}
var responseBody deleteQueryResponse
err = json.NewDecoder(response.Body).Decode(&responseBody)
if err != nil {
return errors.Wrap(err, "decode get query spec response")
}
if responseBody.Err != nil {
return errors.Errorf("get query spec: %s", responseBody.Err)
}
return nil
}

View file

@ -388,22 +388,22 @@ func attachKolideAPIRoutes(r *mux.Router, h *kolideHandlers) {
r.Handle("/api/v1/kolide/queries/{id}", h.ModifyQuery).Methods("PATCH").Name("modify_query")
r.Handle("/api/v1/kolide/queries/{name}", h.DeleteQuery).Methods("DELETE").Name("delete_query")
r.Handle("/api/v1/kolide/queries/delete", h.DeleteQueries).Methods("POST").Name("delete_queries")
r.Handle("/api/v1/kolide/queries/spec", h.ApplyQuerySpecs).Methods("POST").Name("apply_query_specs")
r.Handle("/api/v1/kolide/queries/spec", h.GetQuerySpecs).Methods("GET").Name("get_query_specs")
r.Handle("/api/v1/kolide/spec/queries", h.ApplyQuerySpecs).Methods("POST").Name("apply_query_specs")
r.Handle("/api/v1/kolide/spec/queries", h.GetQuerySpecs).Methods("GET").Name("get_query_specs")
r.Handle("/api/v1/kolide/queries/run", h.CreateDistributedQueryCampaign).Methods("POST").Name("create_distributed_query_campaign")
r.Handle("/api/v1/kolide/packs/{id}", h.GetPack).Methods("GET").Name("get_pack")
r.Handle("/api/v1/kolide/packs", h.ListPacks).Methods("GET").Name("list_packs")
r.Handle("/api/v1/kolide/packs/{name}", h.DeletePack).Methods("DELETE").Name("delete_pack")
r.Handle("/api/v1/kolide/packs/{id}/scheduled", h.GetScheduledQueriesInPack).Methods("GET").Name("get_scheduled_queries_in_pack")
r.Handle("/api/v1/kolide/packs/spec", h.ApplyPackSpecs).Methods("POST").Name("apply_pack_specs")
r.Handle("/api/v1/kolide/packs/spec", h.GetPackSpecs).Methods("GET").Name("get_pack_specs")
r.Handle("/api/v1/kolide/spec/packs", h.ApplyPackSpecs).Methods("POST").Name("apply_pack_specs")
r.Handle("/api/v1/kolide/spec/packs", h.GetPackSpecs).Methods("GET").Name("get_pack_specs")
r.Handle("/api/v1/kolide/labels/{id}", h.GetLabel).Methods("GET").Name("get_label")
r.Handle("/api/v1/kolide/labels", h.ListLabels).Methods("GET").Name("list_labels")
r.Handle("/api/v1/kolide/labels/{name}", h.DeleteLabel).Methods("DELETE").Name("delete_label")
r.Handle("/api/v1/kolide/labels/spec", h.ApplyLabelSpecs).Methods("POST").Name("apply_label_specs")
r.Handle("/api/v1/kolide/labels/spec", h.GetLabelSpecs).Methods("GET").Name("get_label_specs")
r.Handle("/api/v1/kolide/spec/labels", h.ApplyLabelSpecs).Methods("POST").Name("apply_label_specs")
r.Handle("/api/v1/kolide/spec/labels", h.GetLabelSpecs).Methods("GET").Name("get_label_specs")
r.Handle("/api/v1/kolide/hosts", h.ListHosts).Methods("GET").Name("list_hosts")
r.Handle("/api/v1/kolide/host_summary", h.GetHostSummary).Methods("GET").Name("get_host_summary")