fleet/server/service/endpoint_labels.go
Zach Wasserman c6c5e65a7d
Add support for filtering hosts in label (#335)
Support the same query syntax as the hosts endpoint, here also bounded
by the membership of the label.
2021-02-18 12:52:43 -08:00

303 lines
8.5 KiB
Go

package service
import (
"context"
"github.com/fleetdm/fleet/server/kolide"
"github.com/go-kit/kit/endpoint"
)
type getLabelRequest struct {
ID uint
}
type labelResponse struct {
kolide.Label
DisplayText string `json:"display_text"`
Count int `json:"count"`
HostIDs []uint `json:"host_ids"`
}
type getLabelResponse struct {
Label labelResponse `json:"label"`
Err error `json:"error,omitempty"`
}
func (r getLabelResponse) error() error { return r.Err }
func labelResponseForLabel(ctx context.Context, svc kolide.Service, label *kolide.Label) (*labelResponse, error) {
return &labelResponse{
Label: *label,
DisplayText: label.Name,
Count: label.HostCount,
}, nil
}
////////////////////////////////////////////////////////////////////////////////
// Get Label
////////////////////////////////////////////////////////////////////////////////
func makeGetLabelEndpoint(svc kolide.Service) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (interface{}, error) {
req := request.(getLabelRequest)
label, err := svc.GetLabel(ctx, req.ID)
if err != nil {
return getLabelResponse{Err: err}, nil
}
resp, err := labelResponseForLabel(ctx, svc, label)
if err != nil {
return getLabelResponse{Err: err}, nil
}
return getLabelResponse{Label: *resp}, nil
}
}
////////////////////////////////////////////////////////////////////////////////
// Create Label
////////////////////////////////////////////////////////////////////////////////
type createLabelRequest struct {
payload kolide.LabelPayload
}
type createLabelResponse struct {
Label labelResponse `json:"label"`
Err error `json:"error,omitempty"`
}
func (r createLabelResponse) error() error { return r.Err }
func makeCreateLabelEndpoint(svc kolide.Service) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (interface{}, error) {
req := request.(createLabelRequest)
label, err := svc.NewLabel(ctx, req.payload)
if err != nil {
return createLabelResponse{Err: err}, nil
}
labelResp, err := labelResponseForLabel(ctx, svc, label)
if err != nil {
return createLabelResponse{Err: err}, nil
}
return createLabelResponse{Label: *labelResp}, nil
}
}
////////////////////////////////////////////////////////////////////////////////
// Modify Label
////////////////////////////////////////////////////////////////////////////////
type modifyLabelRequest struct {
ID uint
payload kolide.ModifyLabelPayload
}
type modifyLabelResponse struct {
Label labelResponse `json:"label"`
Err error `json:"error,omitempty"`
}
func (r modifyLabelResponse) error() error { return r.Err }
func makeModifyLabelEndpoint(svc kolide.Service) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (interface{}, error) {
req := request.(modifyLabelRequest)
label, err := svc.ModifyLabel(ctx, req.ID, req.payload)
if err != nil {
return modifyLabelResponse{Err: err}, nil
}
labelResp, err := labelResponseForLabel(ctx, svc, label)
if err != nil {
return modifyLabelResponse{Err: err}, nil
}
return modifyLabelResponse{Label: *labelResp}, err
}
}
////////////////////////////////////////////////////////////////////////////////
// List Labels
////////////////////////////////////////////////////////////////////////////////
type listLabelsRequest struct {
ListOptions kolide.ListOptions
}
type listLabelsResponse struct {
Labels []labelResponse `json:"labels"`
Err error `json:"error,omitempty"`
}
func (r listLabelsResponse) error() error { return r.Err }
func makeListLabelsEndpoint(svc kolide.Service) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (interface{}, error) {
req := request.(listLabelsRequest)
labels, err := svc.ListLabels(ctx, req.ListOptions)
if err != nil {
return listLabelsResponse{Err: err}, nil
}
resp := listLabelsResponse{}
for _, label := range labels {
labelResp, err := labelResponseForLabel(ctx, svc, label)
if err != nil {
return listLabelsResponse{Err: err}, nil
}
resp.Labels = append(resp.Labels, *labelResp)
}
return resp, nil
}
}
////////////////////////////////////////////////////////////////////////////////
// List Hosts in Label
////////////////////////////////////////////////////////////////////////////////
type listHostsInLabelRequest struct {
ID uint
ListOptions kolide.HostListOptions
}
func makeListHostsInLabelEndpoint(svc kolide.Service) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (interface{}, error) {
req := request.(listHostsInLabelRequest)
hosts, err := svc.ListHostsInLabel(ctx, req.ID, req.ListOptions)
if err != nil {
return listLabelsResponse{Err: err}, nil
}
hostResponses := make([]HostResponse, len(hosts))
for i, host := range hosts {
h, err := hostResponseForHost(ctx, svc, &host)
if err != nil {
return listHostsResponse{Err: err}, nil
}
hostResponses[i] = *h
}
return listHostsResponse{Hosts: hostResponses}, nil
}
}
////////////////////////////////////////////////////////////////////////////////
// Delete Label
////////////////////////////////////////////////////////////////////////////////
type deleteLabelRequest struct {
Name string
}
type deleteLabelResponse struct {
Err error `json:"error,omitempty"`
}
func (r deleteLabelResponse) error() error { return r.Err }
func makeDeleteLabelEndpoint(svc kolide.Service) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (interface{}, error) {
req := request.(deleteLabelRequest)
err := svc.DeleteLabel(ctx, req.Name)
if err != nil {
return deleteLabelResponse{Err: err}, nil
}
return deleteLabelResponse{}, nil
}
}
////////////////////////////////////////////////////////////////////////////////
// Delete Label By ID
////////////////////////////////////////////////////////////////////////////////
type deleteLabelByIDRequest struct {
ID uint
}
type deleteLabelByIDResponse struct {
Err error `json:"error,omitempty"`
}
func (r deleteLabelByIDResponse) error() error { return r.Err }
func makeDeleteLabelByIDEndpoint(svc kolide.Service) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (interface{}, error) {
req := request.(deleteLabelByIDRequest)
err := svc.DeleteLabelByID(ctx, req.ID)
if err != nil {
return deleteLabelByIDResponse{Err: err}, nil
}
return deleteLabelByIDResponse{}, nil
}
}
////////////////////////////////////////////////////////////////////////////////
// Apply Label Specs
////////////////////////////////////////////////////////////////////////////////
type applyLabelSpecsRequest struct {
Specs []*kolide.LabelSpec `json:"specs"`
}
type applyLabelSpecsResponse struct {
Err error `json:"error,omitempty"`
}
func (r applyLabelSpecsResponse) error() error { return r.Err }
func makeApplyLabelSpecsEndpoint(svc kolide.Service) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (interface{}, error) {
req := request.(applyLabelSpecsRequest)
err := svc.ApplyLabelSpecs(ctx, req.Specs)
if err != nil {
return applyLabelSpecsResponse{Err: err}, nil
}
return applyLabelSpecsResponse{}, nil
}
}
////////////////////////////////////////////////////////////////////////////////
// Get Label Specs
////////////////////////////////////////////////////////////////////////////////
type getLabelSpecsResponse struct {
Specs []*kolide.LabelSpec `json:"specs"`
Err error `json:"error,omitempty"`
}
func (r getLabelSpecsResponse) error() error { return r.Err }
func makeGetLabelSpecsEndpoint(svc kolide.Service) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (interface{}, error) {
specs, err := svc.GetLabelSpecs(ctx)
if err != nil {
return getLabelSpecsResponse{Err: err}, nil
}
return getLabelSpecsResponse{Specs: specs}, nil
}
}
////////////////////////////////////////////////////////////////////////////////
// Get Label Spec
////////////////////////////////////////////////////////////////////////////////
type getLabelSpecResponse struct {
Spec *kolide.LabelSpec `json:"specs,omitempty"`
Err error `json:"error,omitempty"`
}
func (r getLabelSpecResponse) error() error { return r.Err }
func makeGetLabelSpecEndpoint(svc kolide.Service) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (interface{}, error) {
req := request.(getGenericSpecRequest)
spec, err := svc.GetLabelSpec(ctx, req.Name)
if err != nil {
return getLabelSpecResponse{Err: err}, nil
}
return getLabelSpecResponse{Spec: spec}, nil
}
}