diff --git a/client/collector_configuration.go b/client/collector_configuration.go new file mode 100644 index 00000000..c3dfa34a --- /dev/null +++ b/client/collector_configuration.go @@ -0,0 +1,123 @@ +package client + +import ( + "context" + "fmt" + + "github.com/pkg/errors" + "github.com/suzuki-shunsuke/go-set" + + "github.com/suzuki-shunsuke/go-graylog" +) + +// CreateCollectorConfiguration creates a collector configuration. +func (client *Client) CreateCollectorConfiguration(cfg *graylog.CollectorConfiguration) (*ErrorInfo, error) { + return client.CreateCollectorConfigurationContext(context.Background(), cfg) +} + +// CreateCollectorConfigurationContext creates a collector configuration with a context. +func (client *Client) CreateCollectorConfigurationContext( + ctx context.Context, cfg *graylog.CollectorConfiguration, +) (*ErrorInfo, error) { + // POST /plugins/org.graylog.plugins.collector/configurations Create new collector configuration + if cfg == nil { + return nil, fmt.Errorf("collector configuration is nil") + } + if cfg.Inputs == nil { + cfg.Inputs = []graylog.CollectorConfigurationInput{} + } + if cfg.Outputs == nil { + cfg.Outputs = []graylog.CollectorConfigurationOutput{} + } + if cfg.Snippets == nil { + cfg.Snippets = []graylog.CollectorConfigurationSnippet{} + } + if cfg.Tags == nil { + cfg.Tags = set.StrSet{} + } + return client.callPost(ctx, client.Endpoints().CollectorConfigurations(), cfg, cfg) +} + +// GetCollectorConfigurations returns all collector configurations. +func (client *Client) GetCollectorConfigurations() ([]graylog.CollectorConfiguration, int, *ErrorInfo, error) { + return client.GetCollectorConfigurationsContext(context.Background()) +} + +// GetCollectorConfigurationsContext returns all collector configurations with a context. +func (client *Client) GetCollectorConfigurationsContext(ctx context.Context) ([]graylog.CollectorConfiguration, int, *ErrorInfo, error) { + cfgs := &graylog.CollectorConfigurationsBody{} + ei, err := client.callGet( + ctx, client.Endpoints().CollectorConfigurations(), nil, cfgs) + return cfgs.Configurations, cfgs.Total, ei, err +} + +// GetCollectorConfiguration returns a collector configuration. +func (client *Client) GetCollectorConfiguration(id string) (*graylog.CollectorConfiguration, *ErrorInfo, error) { + return client.GetCollectorConfigurationContext(context.Background(), id) +} + +// GetCollectorConfigurationContext returns a given user with a context. +func (client *Client) GetCollectorConfigurationContext( + ctx context.Context, id string, +) (*graylog.CollectorConfiguration, *ErrorInfo, error) { + // GET /api/plugins/org.graylog.plugins.collector/configurations/:id + if id == "" { + return nil, nil, errors.New("id is empty") + } + u, err := client.Endpoints().CollectorConfiguration(id) + if err != nil { + return nil, nil, err + } + cfg := &graylog.CollectorConfiguration{} + ei, err := client.callGet(ctx, u.String(), nil, cfg) + return cfg, ei, err +} + +// RenameCollectorConfiguration renames a collector configuration. +func (client *Client) RenameCollectorConfiguration(id, name string) (*graylog.CollectorConfiguration, *ErrorInfo, error) { + return client.RenameCollectorConfigurationContext(context.Background(), id, name) +} + +// RenameCollectorConfigurationContext renames a collector configuration with a context. +func (client *Client) RenameCollectorConfigurationContext( + ctx context.Context, id, name string, +) (*graylog.CollectorConfiguration, *ErrorInfo, error) { + if id == "" { + return nil, nil, fmt.Errorf("id is nil") + } + if name == "" { + return nil, nil, fmt.Errorf("name is nil") + } + input := graylog.CollectorConfiguration{ + Name: name, + Inputs: []graylog.CollectorConfigurationInput{}, + Outputs: []graylog.CollectorConfigurationOutput{}, + Snippets: []graylog.CollectorConfigurationSnippet{}, + } + u, err := client.Endpoints().CollectorConfigurationName(id) + if err != nil { + return nil, nil, err + } + cfg := graylog.CollectorConfiguration{Name: name} + ei, err := client.callPut(ctx, u.String(), &input, &cfg) + return &cfg, ei, err +} + +// DeleteCollectorConfiguration deletes a collector configuration. +func (client *Client) DeleteCollectorConfiguration(id string) (*ErrorInfo, error) { + return client.DeleteCollectorConfigurationContext(context.Background(), id) +} + +// DeleteCollectorConfigurationContext deletes a collector configuration with a context. +func (client *Client) DeleteCollectorConfigurationContext( + ctx context.Context, id string, +) (*ErrorInfo, error) { + if id == "" { + return nil, errors.New("id is empty") + } + u, err := client.Endpoints().CollectorConfiguration(id) + if err != nil { + return nil, err + } + return client.callDelete(ctx, u.String(), nil, nil) +} diff --git a/client/collector_configuration_input.go b/client/collector_configuration_input.go new file mode 100644 index 00000000..51530fba --- /dev/null +++ b/client/collector_configuration_input.go @@ -0,0 +1,91 @@ +package client + +import ( + "context" + "fmt" + + "github.com/suzuki-shunsuke/go-graylog" +) + +// CreateCollectorConfigurationInput creates a collector configuration input. +func (client *Client) CreateCollectorConfigurationInput( + id string, input *graylog.CollectorConfigurationInput, +) (*ErrorInfo, error) { + return client.CreateCollectorConfigurationInputContext( + context.Background(), id, input) +} + +// CreateCollectorConfigurationInputContext creates a collector configuration input with a context. +func (client *Client) CreateCollectorConfigurationInputContext( + ctx context.Context, id string, input *graylog.CollectorConfigurationInput, +) (*ErrorInfo, error) { + // POST /plugins/org.graylog.plugins.collector/configurations/{id}/inputs Create a configuration input + if id == "" { + return nil, fmt.Errorf("id is required") + } + if input == nil { + return nil, fmt.Errorf("collector configuration is nil") + } + u, err := client.Endpoints().CollectorConfigurationInputs(id) + if err != nil { + return nil, err + } + // 202 no content + return client.callPost(ctx, u.String(), input, nil) +} + +// DeleteCollectorConfigurationInput deletes a collector configuration input. +func (client *Client) DeleteCollectorConfigurationInput(id, inputID string) (*ErrorInfo, error) { + return client.DeleteCollectorConfigurationInputContext( + context.Background(), id, inputID) +} + +// DeleteCollectorConfigurationInputContext deletes a collector configuration input with a context. +func (client *Client) DeleteCollectorConfigurationInputContext( + ctx context.Context, id, inputID string, +) (*ErrorInfo, error) { + // DELETE /plugins/org.graylog.plugins.collector/configurations/{id}/inputs/{inputId} Delete input form configuration + if id == "" { + return nil, fmt.Errorf("id is required") + } + if inputID == "" { + return nil, fmt.Errorf("input id is required") + } + u, err := client.Endpoints().CollectorConfigurationInput(id, inputID) + if err != nil { + return nil, err + } + return client.callDelete( + ctx, u.String(), nil, nil) +} + +// UpdateCollectorConfigurationInput updates a collector configuration input. +func (client *Client) UpdateCollectorConfigurationInput( + id, inputID string, input *graylog.CollectorConfigurationInput, +) (*ErrorInfo, error) { + return client.UpdateCollectorConfigurationInputContext( + context.Background(), id, inputID, input) +} + +// UpdateCollectorConfigurationInputContext updates a collector configuration input with a context. +func (client *Client) UpdateCollectorConfigurationInputContext( + ctx context.Context, id, inputID string, + input *graylog.CollectorConfigurationInput, +) (*ErrorInfo, error) { + // PUT /plugins/org.graylog.plugins.collector/configurations/{id}/inputs/{input_id} Update a configuration input + if id == "" { + return nil, fmt.Errorf("id is required") + } + if inputID == "" { + return nil, fmt.Errorf("input id is required") + } + if input == nil { + return nil, fmt.Errorf("input is nil") + } + u, err := client.Endpoints().CollectorConfigurationInput(id, inputID) + if err != nil { + return nil, err + } + return client.callPut( + ctx, u.String(), input, nil) +} diff --git a/client/collector_configuration_output.go b/client/collector_configuration_output.go new file mode 100644 index 00000000..146cc493 --- /dev/null +++ b/client/collector_configuration_output.go @@ -0,0 +1,91 @@ +package client + +import ( + "context" + "fmt" + + "github.com/suzuki-shunsuke/go-graylog" +) + +// CreateCollectorConfigurationOutput creates a collector configuration output. +func (client *Client) CreateCollectorConfigurationOutput( + id string, output *graylog.CollectorConfigurationOutput, +) (*ErrorInfo, error) { + return client.CreateCollectorConfigurationOutputContext( + context.Background(), id, output) +} + +// CreateCollectorConfigurationOutputContext creates a collector configuration output with a context. +func (client *Client) CreateCollectorConfigurationOutputContext( + ctx context.Context, id string, output *graylog.CollectorConfigurationOutput, +) (*ErrorInfo, error) { + // POST /plugins/org.graylog.plugins.collector/configurations/{id}/outputs Create a configuration output + if id == "" { + return nil, fmt.Errorf("id is required") + } + if output == nil { + return nil, fmt.Errorf("collector configuration is nil") + } + u, err := client.Endpoints().CollectorConfigurationOutputs(id) + if err != nil { + return nil, err + } + // 202 no content + return client.callPost(ctx, u.String(), output, nil) +} + +// DeleteCollectorConfigurationOutput deletes a collector configuration output. +func (client *Client) DeleteCollectorConfigurationOutput(id, outputID string) (*ErrorInfo, error) { + return client.DeleteCollectorConfigurationOutputContext( + context.Background(), id, outputID) +} + +// DeleteCollectorConfigurationOutputContext deletes a collector configuration output with a context. +func (client *Client) DeleteCollectorConfigurationOutputContext( + ctx context.Context, id, outputID string, +) (*ErrorInfo, error) { + // DELETE /plugins/org.graylog.plugins.collector/configurations/{id}/outputs/{outputId} Delete output form configuration + if id == "" { + return nil, fmt.Errorf("id is required") + } + if outputID == "" { + return nil, fmt.Errorf("output id is required") + } + u, err := client.Endpoints().CollectorConfigurationOutput(id, outputID) + if err != nil { + return nil, err + } + return client.callDelete( + ctx, u.String(), nil, nil) +} + +// UpdateCollectorConfigurationOutput updates a collector configuration output. +func (client *Client) UpdateCollectorConfigurationOutput( + id, outputID string, output *graylog.CollectorConfigurationOutput, +) (*ErrorInfo, error) { + return client.UpdateCollectorConfigurationOutputContext( + context.Background(), id, outputID, output) +} + +// UpdateCollectorConfigurationOutputContext updates a collector configuration output with a context. +func (client *Client) UpdateCollectorConfigurationOutputContext( + ctx context.Context, id, outputID string, + output *graylog.CollectorConfigurationOutput, +) (*ErrorInfo, error) { + // PUT /plugins/org.graylog.plugins.collector/configurations/{id}/outputs/{output_id} Update a configuration output + if id == "" { + return nil, fmt.Errorf("id is required") + } + if outputID == "" { + return nil, fmt.Errorf("output id is required") + } + if output == nil { + return nil, fmt.Errorf("output is nil") + } + u, err := client.Endpoints().CollectorConfigurationOutput(id, outputID) + if err != nil { + return nil, err + } + return client.callPut( + ctx, u.String(), output, nil) +} diff --git a/client/collector_configuration_snippet.go b/client/collector_configuration_snippet.go new file mode 100644 index 00000000..ee953e31 --- /dev/null +++ b/client/collector_configuration_snippet.go @@ -0,0 +1,90 @@ +package client + +import ( + "context" + "fmt" + + "github.com/suzuki-shunsuke/go-graylog" +) + +// CreateCollectorConfigurationSnippet creates a collector configuration snippet. +func (client *Client) CreateCollectorConfigurationSnippet( + id string, snippet *graylog.CollectorConfigurationSnippet, +) (*ErrorInfo, error) { + return client.CreateCollectorConfigurationSnippetContext( + context.Background(), id, snippet) +} + +// CreateCollectorConfigurationSnippetContext creates a collector configuration snippet with a context. +func (client *Client) CreateCollectorConfigurationSnippetContext( + ctx context.Context, id string, snippet *graylog.CollectorConfigurationSnippet, +) (*ErrorInfo, error) { + // POST /plugins/org.graylog.plugins.collector/configurations/{id}/snippets Create a configuration snippet + if id == "" { + return nil, fmt.Errorf("id is required") + } + if snippet == nil { + return nil, fmt.Errorf("collector configuration is nil") + } + u, err := client.Endpoints().CollectorConfigurationSnippets(id) + if err != nil { + return nil, err + } + return client.callPost(ctx, u.String(), snippet, nil) +} + +// DeleteCollectorConfigurationSnippet deletes a collector configuration snippet. +func (client *Client) DeleteCollectorConfigurationSnippet(id, snippetID string) (*ErrorInfo, error) { + return client.DeleteCollectorConfigurationSnippetContext( + context.Background(), id, snippetID) +} + +// DeleteCollectorConfigurationSnippetContext deletes a collector configuration snippet with a context. +func (client *Client) DeleteCollectorConfigurationSnippetContext( + ctx context.Context, id, snippetID string, +) (*ErrorInfo, error) { + // DELETE /plugins/org.graylog.plugins.collector/configurations/{id}/snippets/{snippetId} Delete snippet form configuration + if id == "" { + return nil, fmt.Errorf("id is required") + } + if snippetID == "" { + return nil, fmt.Errorf("snippet id is required") + } + u, err := client.Endpoints().CollectorConfigurationSnippet(id, snippetID) + if err != nil { + return nil, err + } + return client.callDelete( + ctx, u.String(), nil, nil) +} + +// UpdateCollectorConfigurationSnippet updates a collector configuration snippet. +func (client *Client) UpdateCollectorConfigurationSnippet( + id, snippetID string, snippet *graylog.CollectorConfigurationSnippet, +) (*ErrorInfo, error) { + return client.UpdateCollectorConfigurationSnippetContext( + context.Background(), id, snippetID, snippet) +} + +// UpdateCollectorConfigurationSnippetContext updates a collector configuration snippet with a context. +func (client *Client) UpdateCollectorConfigurationSnippetContext( + ctx context.Context, id, snippetID string, + snippet *graylog.CollectorConfigurationSnippet, +) (*ErrorInfo, error) { + // PUT /plugins/org.graylog.plugins.collector/configurations/{id}/snippets/{snippet_id} Update a configuration snippet + if id == "" { + return nil, fmt.Errorf("id is required") + } + if snippetID == "" { + return nil, fmt.Errorf("snippet id is required") + } + if snippet == nil { + return nil, fmt.Errorf("snippet is nil") + } + u, err := client.Endpoints().CollectorConfigurationSnippet(id, snippetID) + if err != nil { + return nil, err + } + return client.callPut( + ctx, u.String(), snippet, nil) +} diff --git a/client/endpoint/collector_configuration.go b/client/endpoint/collector_configuration.go new file mode 100644 index 00000000..20e38a80 --- /dev/null +++ b/client/endpoint/collector_configuration.go @@ -0,0 +1,60 @@ +package endpoint + +import ( + "fmt" + "net/url" +) + +// CollectorConfigurations returns a Collector Configuration API's endpoint url. +func (ep *Endpoints) CollectorConfigurations() string { + // /plugins/org.graylog.plugins.collector/configurations + return ep.collectorConfigurations.String() +} + +// CollectorConfiguration returns a Collector Configuration API's endpoint url. +func (ep *Endpoints) CollectorConfiguration(id string) (*url.URL, error) { + // /plugins/org.graylog.plugins.collector/configurations + return urlJoin(ep.collectorConfigurations, id) +} + +// CollectorConfigurationName returns a Collector Configuration API's endpoint url. +func (ep *Endpoints) CollectorConfigurationName(id string) (*url.URL, error) { + // /plugins/org.graylog.plugins.collector/configurations/:id/name + return urlJoin(ep.collectorConfigurations, fmt.Sprintf("%s/name", id)) +} + +// CollectorConfigurationInputs returns a Collector Configuration Input API's endpoint url. +func (ep *Endpoints) CollectorConfigurationInputs(id string) (*url.URL, error) { + // /plugins/org.graylog.plugins.collector/configurations/{id}/inputs + return urlJoin(ep.collectorConfigurations, fmt.Sprintf("%s/inputs", id)) +} + +// CollectorConfigurationInput returns a Collector Configuration Input API's endpoint url. +func (ep *Endpoints) CollectorConfigurationInput(id, inputID string) (*url.URL, error) { + // /plugins/org.graylog.plugins.collector/configurations/{id}/inputs/{inputId} + return urlJoin(ep.collectorConfigurations, fmt.Sprintf("%s/inputs/%s", id, inputID)) +} + +// CollectorConfigurationOutputs returns a Collector Configuration Output API's endpoint url. +func (ep *Endpoints) CollectorConfigurationOutputs(id string) (*url.URL, error) { + // /plugins/org.graylog.plugins.collector/configurations/{id}/outputs + return urlJoin(ep.collectorConfigurations, fmt.Sprintf("%s/outputs", id)) +} + +// CollectorConfigurationOutput returns a Collector Configuration Output API's endpoint url. +func (ep *Endpoints) CollectorConfigurationOutput(id, outputID string) (*url.URL, error) { + // /plugins/org.graylog.plugins.collector/configurations/{id}/outputs/{outputId} + return urlJoin(ep.collectorConfigurations, fmt.Sprintf("%s/outputs/%s", id, outputID)) +} + +// CollectorConfigurationSnippets returns a Collector Configuration Snippet API's endpoint url. +func (ep *Endpoints) CollectorConfigurationSnippets(id string) (*url.URL, error) { + // /plugins/org.graylog.plugins.collector/configurations/{id}/snippets + return urlJoin(ep.collectorConfigurations, fmt.Sprintf("%s/snippets", id)) +} + +// CollectorConfigurationSnippet returns a Collector Configuration Snippet API's endpoint url. +func (ep *Endpoints) CollectorConfigurationSnippet(id, snippetID string) (*url.URL, error) { + // /plugins/org.graylog.plugins.collector/configurations/{id}/snippets/{snippetId} + return urlJoin(ep.collectorConfigurations, fmt.Sprintf("%s/snippets/%s", id, snippetID)) +} diff --git a/client/endpoint/endpoint.go b/client/endpoint/endpoint.go index a6b18987..2d0d0b3f 100644 --- a/client/endpoint/endpoint.go +++ b/client/endpoint/endpoint.go @@ -12,18 +12,19 @@ func urlJoin(ep *url.URL, arg string) (*url.URL, error) { // Endpoints represents each API's endpoint URLs. type Endpoints struct { - alarmCallbacks *url.URL - alerts *url.URL - alertConditions *url.URL - dashboards *url.URL - enabledStreams *url.URL - indexSets *url.URL - indexSetStats *url.URL - inputs *url.URL - roles *url.URL - streams *url.URL - users *url.URL - ldapSetting string + alarmCallbacks *url.URL + alerts *url.URL + alertConditions *url.URL + collectorConfigurations *url.URL + dashboards *url.URL + enabledStreams *url.URL + indexSets *url.URL + indexSetStats *url.URL + inputs *url.URL + roles *url.URL + streams *url.URL + users *url.URL + ldapSetting string } // NewEndpoints returns a new Endpoints. @@ -43,6 +44,10 @@ func NewEndpoints(endpoint string) (*Endpoints, error) { if err != nil { return nil, err } + collectorConfigurations, err := urlJoin(ep, "plugins/org.graylog.plugins.collector/configurations") + if err != nil { + return nil, err + } dashboards, err := urlJoin(ep, "dashboards") if err != nil { return nil, err @@ -84,17 +89,18 @@ func NewEndpoints(endpoint string) (*Endpoints, error) { return nil, err } return &Endpoints{ - alarmCallbacks: alarmCallbacks, - alerts: alerts, - alertConditions: alertConditions, - dashboards: dashboards, - enabledStreams: enabledStreams, - indexSets: indexSets, - indexSetStats: indexSetStats, - inputs: inputs, - roles: roles, - streams: streams, - users: users, - ldapSetting: ldapSetting.String(), + alarmCallbacks: alarmCallbacks, + alerts: alerts, + alertConditions: alertConditions, + collectorConfigurations: collectorConfigurations, + dashboards: dashboards, + enabledStreams: enabledStreams, + indexSets: indexSets, + indexSetStats: indexSetStats, + inputs: inputs, + roles: roles, + streams: streams, + users: users, + ldapSetting: ldapSetting.String(), }, nil } diff --git a/collector_configuration.go b/collector_configuration.go new file mode 100644 index 00000000..1eeb56e7 --- /dev/null +++ b/collector_configuration.go @@ -0,0 +1,75 @@ +package graylog + +import ( + "github.com/suzuki-shunsuke/go-set" +) + +type ( + // CollectorConfiguration represents a Graylog's Collector Configuration. + CollectorConfiguration struct { + ID string `json:"id,omitempty" v-create:"isdefault"` + Name string `json:"name,omitempty" v-create:"required"` + Tags set.StrSet `json:"tags"` + Inputs []CollectorConfigurationInput `json:"inputs"` + Outputs []CollectorConfigurationOutput `json:"outputs"` + Snippets []CollectorConfigurationSnippet `json:"snippets"` + } + + // CollectorConfigurationInput represents a Graylog's Collector Configuration Input. + CollectorConfigurationInput struct { + Backend string `json:"backend"` + Type string `json:"type"` + Name string `json:"name"` + InputID string `json:"input_id"` + ForwardTo string `json:"forward_to"` + Properties CollectorConfigurationInputProperty `json:"properties"` + } + + // CollectorConfigurationInputProperty represents a Graylog's Collector Configuration Input properties. + CollectorConfigurationInputProperty interface{} + + // CollectorConfigurationInputFileProperty represents a Graylog's Collector Configuration file type Input properties. + CollectorConfigurationInputFileProperty struct { + Paths string `json:"paths"` + ExcludeFiles string `json:"exclude_files"` + ScanFrequency string `json:"scan_frequency"` + Encoding string `json:"encoding"` + IgnoreOlder string `json:"ignore_older"` + DocumentType string `json:"document_type"` + ExcludeLines string `json:"exclude_lines"` + IncludeLines string `json:"include_lines"` + TailFiles bool `json:"tail_files"` + } + + // CollectorConfigurationInputWindowsEventLogProperty represents a Graylog's Collector Configuration windows event log type Input properties. + CollectorConfigurationInputWindowsEventLogProperty struct { + Event string `json:"event"` + } + + // CollectorConfigurationOutput represents a Graylog's Collector Configuration Output. + CollectorConfigurationOutput struct { + Backend string `json:"backend"` + Type string `json:"type"` + Name string `json:"name"` + OutputID string `json:"output_id"` + Properties CollectorConfigurationOutputProperty `json:"properties"` + } + + // CollectorConfigurationOutputProperty represents a Graylog's Collector Configuration Output properties. + CollectorConfigurationOutputProperty interface{} + + // CollectorConfigurationSnippet represents a Graylog's Collector Configuration Snippet. + CollectorConfigurationSnippet struct { + Backend string `json:"backend"` + Name string `json:"name"` + Snippet string `json:"snippet"` + SnippetID string `json:"snippet_id"` + } +) + +// CollectorConfigurationsBody represents Get Collector Configurations API's response body. +// Basically users don't use this struct, but this struct is public because some sub packages use this struct. +type CollectorConfigurationsBody struct { + Configurations []CollectorConfiguration `json:"configurations"` + Total int `json:"total"` +} diff --git a/mockserver/handler/collector_configuration.go b/mockserver/handler/collector_configuration.go new file mode 100644 index 00000000..8f4f7593 --- /dev/null +++ b/mockserver/handler/collector_configuration.go @@ -0,0 +1,122 @@ +package handler + +import ( + "net/http" + + log "github.com/sirupsen/logrus" + "github.com/suzuki-shunsuke/go-set" + + "github.com/suzuki-shunsuke/go-graylog" + "github.com/suzuki-shunsuke/go-graylog/mockserver/logic" + "github.com/suzuki-shunsuke/go-graylog/util" +) + +// HandleGetCollectorConfiguration is the handler of Get an CollectorConfiguration API. +func HandleGetCollectorConfiguration( + user *graylog.User, lgc *logic.Logic, r *http.Request, ps Params, +) (interface{}, int, error) { + // GET /api/plugins/org.graylog.plugins.collector/configurations/:id + id := ps.PathParam("collectorConfigurationID") + // TODO authorize + return lgc.GetCollectorConfiguration(id) +} + +// HandleGetCollectorConfigurations is the handler of Get Collector Configurations API. +func HandleGetCollectorConfigurations( + user *graylog.User, lgc *logic.Logic, r *http.Request, ps Params, +) (interface{}, int, error) { + // GET /plugins/org.graylog.plugins.collector/configurations List all collector configurations + arr, total, sc, err := lgc.GetCollectorConfigurations() + if err != nil { + return arr, sc, err + } + cfgs := &graylog.CollectorConfigurationsBody{Configurations: arr, Total: total} + return cfgs, sc, nil +} + +// HandleCreateCollectorConfiguration is the handler of Create an CollectorConfiguration API. +func HandleCreateCollectorConfiguration( + user *graylog.User, lgc *logic.Logic, r *http.Request, ps Params, +) (interface{}, int, error) { + // POST /system/inputs Launch input on this node + // TODO authorize + body, sc, err := validateRequestBody( + r.Body, &validateReqBodyPrms{ + Required: set.NewStrSet("tags", "inputs", "outputs", "snippets"), + Optional: set.NewStrSet("name", "id"), + ExtForbidden: true, + }) + if err != nil { + return nil, sc, err + } + cfg := &graylog.CollectorConfiguration{} + if err := util.MSDecode(body, cfg); err != nil { + lgc.Logger().WithFields(log.Fields{ + "body": body, "error": err, + }).Info("Failed to parse request body as CollectorConfiguration") + return nil, 400, err + } + sc, err = lgc.AddCollectorConfiguration(cfg) + if err != nil { + return nil, sc, err + } + if err := lgc.Save(); err != nil { + return nil, 500, err + } + return cfg, sc, nil +} + +// HandleRenameCollectorConfiguration is the handler of Rename a CollectorConfiguration API. +func HandleRenameCollectorConfiguration( + user *graylog.User, lgc *logic.Logic, r *http.Request, ps Params, +) (interface{}, int, error) { + // PUT /plugins/org.graylog.plugins.collector/configurations/{id}/name Updates a collector configuration name + id := ps.PathParam("collectorConfigurationID") + // TODO authorize + body, sc, err := validateRequestBody( + r.Body, &validateReqBodyPrms{ + Required: set.NewStrSet("tags", "inputs", "outputs", "snippets"), + Optional: set.NewStrSet("name", "id"), + ExtForbidden: true, + }) + if err != nil { + return nil, sc, err + } + prms := &graylog.CollectorConfiguration{} + if err := util.MSDecode(body, prms); err != nil { + lgc.Logger().WithFields(log.Fields{ + "body": body, "error": err, + }).Info("Failed to parse request body as CollectorConfiguration") + return nil, 400, err + } + + lgc.Logger().WithFields(log.Fields{ + "body": body, "input": prms, "id": id, + }).Debug("request body") + + cfg, sc, err := lgc.RenameCollectorConfiguration(id, prms.Name) + if err != nil { + return nil, sc, err + } + if err := lgc.Save(); err != nil { + return nil, 500, err + } + return cfg, sc, nil +} + +// HandleDeleteCollectorConfiguration is the handler of Delete an CollectorConfiguration API. +func HandleDeleteCollectorConfiguration( + user *graylog.User, lgc *logic.Logic, r *http.Request, ps Params, +) (interface{}, int, error) { + // DELETE /plugins/org.graylog.plugins.collector/configurations/{id} Delete a collector configuration + id := ps.PathParam("collectorConfigurationID") + // TODO authorize + sc, err := lgc.DeleteCollectorConfiguration(id) + if err != nil { + return nil, sc, err + } + if err := lgc.Save(); err != nil { + return nil, 500, err + } + return nil, sc, nil +} diff --git a/mockserver/handler/collector_configuration_input.go b/mockserver/handler/collector_configuration_input.go new file mode 100644 index 00000000..60af5bc0 --- /dev/null +++ b/mockserver/handler/collector_configuration_input.go @@ -0,0 +1,106 @@ +package handler + +import ( + "net/http" + + log "github.com/sirupsen/logrus" + "github.com/suzuki-shunsuke/go-set" + + "github.com/suzuki-shunsuke/go-graylog" + "github.com/suzuki-shunsuke/go-graylog/mockserver/logic" + "github.com/suzuki-shunsuke/go-graylog/util" +) + +// HandleCreateCollectorConfigurationInput is the handler of Create a CollectorConfiguration Input API. +func HandleCreateCollectorConfigurationInput( + user *graylog.User, lgc *logic.Logic, r *http.Request, ps Params, +) (interface{}, int, error) { + // TODO authorize + cfgID := ps.PathParam("collectorConfigurationID") + // Known properties include: input_id, properties, backend, forward_to, type, name + body, sc, err := validateRequestBody( + r.Body, &validateReqBodyPrms{ + Required: set.NewStrSet("backend", "type", "name", "forward_to"), + Optional: set.NewStrSet("properties"), + Ignored: set.NewStrSet("input_id"), + ExtForbidden: true, + }) + if err != nil { + return nil, sc, err + } + input := &graylog.CollectorConfigurationInput{} + if err := util.MSDecode(body, input); err != nil { + lgc.Logger().WithFields(log.Fields{ + "body": body, "error": err, + }).Info("Failed to parse request body as CollectorConfigurationInput") + return nil, 400, err + } + sc, err = lgc.AddCollectorConfigurationInput(cfgID, input) + if err != nil { + return nil, sc, err + } + if err := lgc.Save(); err != nil { + return nil, 500, err + } + // 202 no content + return nil, sc, nil +} + +// HandleUpdateCollectorConfigurationInput is the handler of Update a CollectorConfiguration Input API. +func HandleUpdateCollectorConfigurationInput( + user *graylog.User, lgc *logic.Logic, r *http.Request, ps Params, +) (interface{}, int, error) { + cfgID := ps.PathParam("collectorConfigurationID") + inputID := ps.PathParam("collectorConfigurationInputID") + // TODO authorize + body, sc, err := validateRequestBody( + r.Body, &validateReqBodyPrms{ + Required: set.NewStrSet("backend", "type", "name", "forward_to"), + Optional: set.NewStrSet("properties"), + Ignored: set.NewStrSet("input_id"), + ExtForbidden: true, + }) + if err != nil { + return nil, sc, err + } + input := &graylog.CollectorConfigurationInput{} + if err := util.MSDecode(body, input); err != nil { + lgc.Logger().WithFields(log.Fields{ + "body": body, "error": err, + }).Info("Failed to parse request body as CollectorConfiguration Input") + return nil, 400, err + } + + lgc.Logger().WithFields(log.Fields{ + "body": body, "input": input, + "collector_configuration_id": cfgID, + "collector_configuration_input_id": inputID, + }).Debug("request body") + + sc, err = lgc.UpdateCollectorConfigurationInput(cfgID, inputID, input) + if err != nil { + return nil, sc, err + } + if err := lgc.Save(); err != nil { + return nil, 500, err + } + // 202 no content + return nil, sc, nil +} + +// HandleDeleteCollectorConfigurationInput is the handler of Delete an CollectorConfiguration Input API. +func HandleDeleteCollectorConfigurationInput( + user *graylog.User, lgc *logic.Logic, r *http.Request, ps Params, +) (interface{}, int, error) { + id := ps.PathParam("collectorConfigurationID") + inputID := ps.PathParam("collectorConfigurationInputID") + // TODO authorize + sc, err := lgc.DeleteCollectorConfigurationInput(id, inputID) + if err != nil { + return nil, sc, err + } + if err := lgc.Save(); err != nil { + return nil, 500, err + } + return nil, sc, nil +} diff --git a/mockserver/handler/collector_configuration_output.go b/mockserver/handler/collector_configuration_output.go new file mode 100644 index 00000000..e749331c --- /dev/null +++ b/mockserver/handler/collector_configuration_output.go @@ -0,0 +1,106 @@ +package handler + +import ( + "net/http" + + log "github.com/sirupsen/logrus" + "github.com/suzuki-shunsuke/go-set" + + "github.com/suzuki-shunsuke/go-graylog" + "github.com/suzuki-shunsuke/go-graylog/mockserver/logic" + "github.com/suzuki-shunsuke/go-graylog/util" +) + +// HandleCreateCollectorConfigurationOutput is the handler of Create a CollectorConfiguration Output API. +func HandleCreateCollectorConfigurationOutput( + user *graylog.User, lgc *logic.Logic, r *http.Request, ps Params, +) (interface{}, int, error) { + // TODO authorize + cfgID := ps.PathParam("collectorConfigurationID") + // Known properties include: output_id, type, name, backend, properties + body, sc, err := validateRequestBody( + r.Body, &validateReqBodyPrms{ + Required: set.NewStrSet("type", "name", "backend"), + Optional: set.NewStrSet("properties"), + Ignored: set.NewStrSet("output_id"), + ExtForbidden: true, + }) + if err != nil { + return nil, sc, err + } + output := &graylog.CollectorConfigurationOutput{} + if err := util.MSDecode(body, output); err != nil { + lgc.Logger().WithFields(log.Fields{ + "body": body, "error": err, + }).Info("Failed to parse request body as CollectorConfigurationOutput") + return nil, 400, err + } + sc, err = lgc.AddCollectorConfigurationOutput(cfgID, output) + if err != nil { + return nil, sc, err + } + if err := lgc.Save(); err != nil { + return nil, 500, err + } + // 202 no content + return nil, sc, nil +} + +// HandleUpdateCollectorConfigurationOutput is the handler of Update a CollectorConfiguration Output API. +func HandleUpdateCollectorConfigurationOutput( + user *graylog.User, lgc *logic.Logic, r *http.Request, ps Params, +) (interface{}, int, error) { + cfgID := ps.PathParam("collectorConfigurationID") + outputID := ps.PathParam("collectorConfigurationOutputID") + // TODO authorize + body, sc, err := validateRequestBody( + r.Body, &validateReqBodyPrms{ + Required: set.NewStrSet("backend", "type", "name"), + Optional: set.NewStrSet("properties"), + Ignored: set.NewStrSet("output_id"), + ExtForbidden: true, + }) + if err != nil { + return nil, sc, err + } + output := &graylog.CollectorConfigurationOutput{} + if err := util.MSDecode(body, output); err != nil { + lgc.Logger().WithFields(log.Fields{ + "body": body, "error": err, + }).Info("Failed to parse request body as CollectorConfiguration Output") + return nil, 400, err + } + + lgc.Logger().WithFields(log.Fields{ + "body": body, "output": output, + "collector_configuration_id": cfgID, + "collector_configuration_output_id": outputID, + }).Debug("request body") + + sc, err = lgc.UpdateCollectorConfigurationOutput(cfgID, outputID, output) + if err != nil { + return nil, sc, err + } + if err := lgc.Save(); err != nil { + return nil, 500, err + } + // 202 no content + return nil, sc, nil +} + +// HandleDeleteCollectorConfigurationOutput is the handler of Delete an CollectorConfiguration Output API. +func HandleDeleteCollectorConfigurationOutput( + user *graylog.User, lgc *logic.Logic, r *http.Request, ps Params, +) (interface{}, int, error) { + id := ps.PathParam("collectorConfigurationID") + outputID := ps.PathParam("collectorConfigurationOutputID") + // TODO authorize + sc, err := lgc.DeleteCollectorConfigurationOutput(id, outputID) + if err != nil { + return nil, sc, err + } + if err := lgc.Save(); err != nil { + return nil, 500, err + } + return nil, sc, nil +} diff --git a/mockserver/handler/collector_configuration_snippet.go b/mockserver/handler/collector_configuration_snippet.go new file mode 100644 index 00000000..35c34422 --- /dev/null +++ b/mockserver/handler/collector_configuration_snippet.go @@ -0,0 +1,103 @@ +package handler + +import ( + "net/http" + + log "github.com/sirupsen/logrus" + "github.com/suzuki-shunsuke/go-set" + + "github.com/suzuki-shunsuke/go-graylog" + "github.com/suzuki-shunsuke/go-graylog/mockserver/logic" + "github.com/suzuki-shunsuke/go-graylog/util" +) + +// HandleCreateCollectorConfigurationSnippet is the handler of Create a CollectorConfiguration Snippet API. +func HandleCreateCollectorConfigurationSnippet( + user *graylog.User, lgc *logic.Logic, r *http.Request, ps Params, +) (interface{}, int, error) { + // TODO authorize + cfgID := ps.PathParam("collectorConfigurationSnippetID") + body, sc, err := validateRequestBody( + r.Body, &validateReqBodyPrms{ + Required: set.NewStrSet("tags", "snippets", "outputs", "snippets"), + Optional: nil, + ExtForbidden: true, + }) + if err != nil { + return nil, sc, err + } + snippet := &graylog.CollectorConfigurationSnippet{} + if err := util.MSDecode(body, snippet); err != nil { + lgc.Logger().WithFields(log.Fields{ + "body": body, "error": err, + }).Info("Failed to parse request body as CollectorConfigurationSnippet") + return nil, 400, err + } + sc, err = lgc.AddCollectorConfigurationSnippet(cfgID, snippet) + if err != nil { + return nil, sc, err + } + if err := lgc.Save(); err != nil { + return nil, 500, err + } + // 202 no content + return nil, sc, nil +} + +// HandleUpdateCollectorConfigurationSnippet is the handler of Update a CollectorConfiguration Snippet API. +func HandleUpdateCollectorConfigurationSnippet( + user *graylog.User, lgc *logic.Logic, r *http.Request, ps Params, +) (interface{}, int, error) { + cfgID := ps.PathParam("collectorConfigurationID") + snippetID := ps.PathParam("collectorConfigurationSnippetID") + // TODO authorize + body, sc, err := validateRequestBody( + r.Body, &validateReqBodyPrms{ + Required: set.NewStrSet("backend", "name", "snippet"), + Ignored: set.NewStrSet("snippet_id"), + ExtForbidden: true, + }) + if err != nil { + return nil, sc, err + } + snippet := &graylog.CollectorConfigurationSnippet{} + if err := util.MSDecode(body, snippet); err != nil { + lgc.Logger().WithFields(log.Fields{ + "body": body, "error": err, + }).Info("Failed to parse request body as CollectorConfiguration Snippet") + return nil, 400, err + } + + lgc.Logger().WithFields(log.Fields{ + "body": body, "snippet": snippet, + "collector_configuration_id": cfgID, + "collector_configuration_snippet_id": snippetID, + }).Debug("request body") + + sc, err = lgc.UpdateCollectorConfigurationSnippet(cfgID, snippetID, snippet) + if err != nil { + return nil, sc, err + } + if err := lgc.Save(); err != nil { + return nil, 500, err + } + // 202 no content + return nil, sc, nil +} + +// HandleDeleteCollectorConfigurationSnippet is the handler of Delete an CollectorConfiguration Snippet API. +func HandleDeleteCollectorConfigurationSnippet( + user *graylog.User, lgc *logic.Logic, r *http.Request, ps Params, +) (interface{}, int, error) { + id := ps.PathParam("collectorConfigurationID") + snippetID := ps.PathParam("collectorConfigurationSnippetID") + // TODO authorize + sc, err := lgc.DeleteCollectorConfigurationSnippet(id, snippetID) + if err != nil { + return nil, sc, err + } + if err := lgc.Save(); err != nil { + return nil, 500, err + } + return nil, sc, nil +} diff --git a/mockserver/handler/router.go b/mockserver/handler/router.go index 0e8deecf..edbeeffb 100644 --- a/mockserver/handler/router.go +++ b/mockserver/handler/router.go @@ -25,6 +25,56 @@ func NewRouter(lgc *logic.Logic) http.Handler { e.PUT("/api/dashboards/:dashboardID", wrapEchoHandle(lgc, HandleUpdateDashboard)) e.DELETE("/api/dashboards/:dashboardID", wrapEchoHandle(lgc, HandleDeleteDashboard)) + // Collector Configuration + e.GET( + "/api/plugins/org.graylog.plugins.collector/configurations", + wrapEchoHandle(lgc, HandleGetCollectorConfigurations)) + e.POST( + "/api/plugins/org.graylog.plugins.collector/configurations", + wrapEchoHandle(lgc, HandleCreateCollectorConfiguration)) + e.PUT( + "/api/plugins/org.graylog.plugins.collector/configurations/:collectorConfigurationID/name", + wrapEchoHandle(lgc, HandleRenameCollectorConfiguration)) + e.GET( + "/api/plugins/org.graylog.plugins.collector/configurations/:collectorConfigurationID", + wrapEchoHandle(lgc, HandleGetCollectorConfiguration)) + e.DELETE( + "/api/plugins/org.graylog.plugins.collector/configurations/:collectorConfigurationID", + wrapEchoHandle(lgc, HandleDeleteCollectorConfiguration)) + + // Collector Configuration Input + e.POST( + "/api/plugins/org.graylog.plugins.collector/configurations/:collectorConfigurationID/inputs", + wrapEchoHandle(lgc, HandleCreateCollectorConfigurationInput)) + e.PUT( + "/api/plugins/org.graylog.plugins.collector/configurations/:collectorConfigurationID/inputs/:collectorConfigurationInputID", + wrapEchoHandle(lgc, HandleUpdateCollectorConfigurationInput)) + e.DELETE( + "/api/plugins/org.graylog.plugins.collector/configurations/:collectorConfigurationID/inputs/:collectorConfigurationInputID", + wrapEchoHandle(lgc, HandleDeleteCollectorConfigurationInput)) + + // Collector Configuration Output + e.POST( + "/api/plugins/org.graylog.plugins.collector/configurations/:collectorConfigurationID/outputs", + wrapEchoHandle(lgc, HandleCreateCollectorConfigurationOutput)) + e.PUT( + "/api/plugins/org.graylog.plugins.collector/configurations/:collectorConfigurationID/outputs/:collectorConfigurationOutputID", + wrapEchoHandle(lgc, HandleUpdateCollectorConfigurationOutput)) + e.DELETE( + "/api/plugins/org.graylog.plugins.collector/configurations/:collectorConfigurationID/outputs/:collectorConfigurationOutputID", + wrapEchoHandle(lgc, HandleDeleteCollectorConfigurationOutput)) + + // Collector Configuration Snippet + e.POST( + "/api/plugins/org.graylog.plugins.collector/configurations/:collectorConfigurationID/snippets", + wrapEchoHandle(lgc, HandleCreateCollectorConfigurationSnippet)) + e.PUT( + "/api/plugins/org.graylog.plugins.collector/configurations/:collectorConfigurationID/snippets/:collectorConfigurationSnippetID", + wrapEchoHandle(lgc, HandleUpdateCollectorConfigurationSnippet)) + e.DELETE( + "/api/plugins/org.graylog.plugins.collector/configurations/:collectorConfigurationID/snippets/:collectorConfigurationSnippetID", + wrapEchoHandle(lgc, HandleDeleteCollectorConfigurationSnippet)) + // Role e.GET("/api/roles/:rolename", wrapEchoHandle(lgc, HandleGetRole)) e.GET("/api/roles", wrapEchoHandle(lgc, HandleGetRoles)) diff --git a/mockserver/logic/collector_configuration.go b/mockserver/logic/collector_configuration.go new file mode 100644 index 00000000..c8d744b6 --- /dev/null +++ b/mockserver/logic/collector_configuration.go @@ -0,0 +1,96 @@ +package logic + +import ( + "fmt" + + log "github.com/sirupsen/logrus" + + "github.com/suzuki-shunsuke/go-graylog" + "github.com/suzuki-shunsuke/go-graylog/validator" +) + +// HasCollectorConfiguration returns whether the collector configuration exists. +func (lgc *Logic) HasCollectorConfiguration(id string) (bool, error) { + return lgc.store.HasCollectorConfiguration(id) +} + +// GetCollectorConfiguration returns a collector configuration. +// If a collector configuration is not found, returns an error. +func (lgc *Logic) GetCollectorConfiguration(id string) (*graylog.CollectorConfiguration, int, error) { + if id == "" { + return nil, 400, fmt.Errorf("collector configuration id is required") + } + if err := ValidateObjectID(id); err != nil { + // unfortunately graylog returns not 400 but 404. + return nil, 404, err + } + cfg, err := lgc.store.GetCollectorConfiguration(id) + if err != nil { + return cfg, 500, err + } + if cfg == nil { + return nil, 404, fmt.Errorf("no collector configuration with id <%s> is found", id) + } + return cfg, 200, nil +} + +// AddCollectorConfiguration adds a collector configuration to the mock server. +func (lgc *Logic) AddCollectorConfiguration(cfg *graylog.CollectorConfiguration) (int, error) { + if err := validator.CreateValidator.Struct(cfg); err != nil { + return 400, err + } + if err := lgc.store.AddCollectorConfiguration(cfg); err != nil { + return 500, err + } + return 200, nil +} + +// RenameCollectorConfiguration renames a collector configuration. +func (lgc *Logic) RenameCollectorConfiguration(id, name string) (*graylog.CollectorConfiguration, int, error) { + if id == "" { + return nil, 400, fmt.Errorf("id is required") + } + if name == "" { + return nil, 400, fmt.Errorf("name is required") + } + ok, err := lgc.HasCollectorConfiguration(id) + if err != nil { + return nil, 500, err + } + if !ok { + return nil, 404, fmt.Errorf("the collector configuration <%s> is not found", id) + } + + cfg, err := lgc.store.RenameCollectorConfiguration(id, name) + if err != nil { + return nil, 500, err + } + return cfg, 200, nil +} + +// DeleteCollectorConfiguration deletes a collector configuration from the mock server. +func (lgc *Logic) DeleteCollectorConfiguration(id string) (int, error) { + ok, err := lgc.HasCollectorConfiguration(id) + if err != nil { + lgc.Logger().WithFields(log.Fields{ + "error": err, "id": id, + }).Error("lgc.HasCollectorConfiguration() is failure") + return 500, err + } + if !ok { + return 404, fmt.Errorf("the collector configuration <%s> is not found", id) + } + if err := lgc.store.DeleteCollectorConfiguration(id); err != nil { + return 500, err + } + return 200, nil +} + +// GetCollectorConfigurations returns a list of collector configurations. +func (lgc *Logic) GetCollectorConfigurations() ([]graylog.CollectorConfiguration, int, int, error) { + cfgs, total, err := lgc.store.GetCollectorConfigurations() + if err != nil { + return nil, 0, 500, err + } + return cfgs, total, 200, nil +} diff --git a/mockserver/logic/collector_configuration_input.go b/mockserver/logic/collector_configuration_input.go new file mode 100644 index 00000000..9e9c49ff --- /dev/null +++ b/mockserver/logic/collector_configuration_input.go @@ -0,0 +1,77 @@ +package logic + +import ( + "fmt" + + log "github.com/sirupsen/logrus" + + "github.com/suzuki-shunsuke/go-graylog" + "github.com/suzuki-shunsuke/go-graylog/validator" +) + +// HasCollectorConfigurationInput returns whether the collector configuration exists. +func (lgc *Logic) HasCollectorConfigurationInput(cfgID, inputID string) (bool, error) { + return lgc.store.HasCollectorConfigurationInput(cfgID, inputID) +} + +// AddCollectorConfigurationInput adds a collector configuration input to the mock server. +func (lgc *Logic) AddCollectorConfigurationInput(id string, input *graylog.CollectorConfigurationInput) (int, error) { + if id == "" { + return 400, fmt.Errorf("id is required") + } + if err := validator.CreateValidator.Struct(input); err != nil { + return 400, err + } + if err := lgc.store.AddCollectorConfigurationInput(id, input); err != nil { + return 500, err + } + // 202 no content + return 202, nil +} + +// UpdateCollectorConfigurationInput updates a collector configuration input. +func (lgc *Logic) UpdateCollectorConfigurationInput( + cfgID, inputID string, input *graylog.CollectorConfigurationInput, +) (int, error) { + if cfgID == "" { + return 400, fmt.Errorf("collector configuration id is required") + } + if inputID == "" { + return 400, fmt.Errorf("collector configuration input id is required") + } + if err := validator.UpdateValidator.Struct(input); err != nil { + return 400, err + } + ok, err := lgc.HasCollectorConfigurationInput(cfgID, inputID) + if err != nil { + return 500, err + } + if !ok { + return 404, fmt.Errorf("the collector configuration input is not found") + } + + if err := lgc.store.UpdateCollectorConfigurationInput(cfgID, inputID, input); err != nil { + return 500, err + } + // 202 no content + return 200, nil +} + +// DeleteCollectorConfigurationInput deletes a collector configuration input from the mock server. +func (lgc *Logic) DeleteCollectorConfigurationInput(cfgID, inputID string) (int, error) { + ok, err := lgc.HasCollectorConfigurationInput(cfgID, inputID) + if err != nil { + lgc.Logger().WithFields(log.Fields{ + "error": err, "configuration_id": cfgID, + "input_id": inputID, + }).Error("failed to check whether the collector configuration exists") + return 500, err + } + if !ok { + return 404, fmt.Errorf("the collector configuration input is not found") + } + if err := lgc.store.DeleteCollectorConfigurationInput(cfgID, inputID); err != nil { + return 500, err + } + return 204, nil +} diff --git a/mockserver/logic/collector_configuration_output.go b/mockserver/logic/collector_configuration_output.go new file mode 100644 index 00000000..bbbf82c7 --- /dev/null +++ b/mockserver/logic/collector_configuration_output.go @@ -0,0 +1,77 @@ +package logic + +import ( + "fmt" + + log "github.com/sirupsen/logrus" + + "github.com/suzuki-shunsuke/go-graylog" + "github.com/suzuki-shunsuke/go-graylog/validator" +) + +// HasCollectorConfigurationOutput returns whether the collector configuration exists. +func (lgc *Logic) HasCollectorConfigurationOutput(cfgID, outputID string) (bool, error) { + return lgc.store.HasCollectorConfigurationOutput(cfgID, outputID) +} + +// AddCollectorConfigurationOutput adds a collector configuration output to the mock server. +func (lgc *Logic) AddCollectorConfigurationOutput(id string, output *graylog.CollectorConfigurationOutput) (int, error) { + if id == "" { + return 400, fmt.Errorf("id is required") + } + if err := validator.CreateValidator.Struct(output); err != nil { + return 400, err + } + if err := lgc.store.AddCollectorConfigurationOutput(id, output); err != nil { + return 500, err + } + // 202 no content + return 202, nil +} + +// UpdateCollectorConfigurationOutput updates a collector configuration output. +func (lgc *Logic) UpdateCollectorConfigurationOutput( + cfgID, outputID string, output *graylog.CollectorConfigurationOutput, +) (int, error) { + if cfgID == "" { + return 400, fmt.Errorf("collector configuration id is required") + } + if outputID == "" { + return 400, fmt.Errorf("collector configuration output id is required") + } + if err := validator.UpdateValidator.Struct(output); err != nil { + return 400, err + } + ok, err := lgc.HasCollectorConfigurationOutput(cfgID, outputID) + if err != nil { + return 500, err + } + if !ok { + return 404, fmt.Errorf("the collector configuration output is not found") + } + + if err := lgc.store.UpdateCollectorConfigurationOutput(cfgID, outputID, output); err != nil { + return 500, err + } + // 202 no content + return 200, nil +} + +// DeleteCollectorConfigurationOutput deletes a collector configuration output from the mock server. +func (lgc *Logic) DeleteCollectorConfigurationOutput(cfgID, outputID string) (int, error) { + ok, err := lgc.HasCollectorConfigurationOutput(cfgID, outputID) + if err != nil { + lgc.Logger().WithFields(log.Fields{ + "error": err, "configuration_id": cfgID, + "output_id": outputID, + }).Error("failed to check whether the collector configuration exists") + return 500, err + } + if !ok { + return 404, fmt.Errorf("the collector configuration output is not found") + } + if err := lgc.store.DeleteCollectorConfigurationOutput(cfgID, outputID); err != nil { + return 500, err + } + return 204, nil +} diff --git a/mockserver/logic/collector_configuration_snippet.go b/mockserver/logic/collector_configuration_snippet.go new file mode 100644 index 00000000..1ec4807e --- /dev/null +++ b/mockserver/logic/collector_configuration_snippet.go @@ -0,0 +1,77 @@ +package logic + +import ( + "fmt" + + log "github.com/sirupsen/logrus" + + "github.com/suzuki-shunsuke/go-graylog" + "github.com/suzuki-shunsuke/go-graylog/validator" +) + +// HasCollectorConfigurationSnippet returns whether the collector configuration exists. +func (lgc *Logic) HasCollectorConfigurationSnippet(cfgID, snippetID string) (bool, error) { + return lgc.store.HasCollectorConfigurationSnippet(cfgID, snippetID) +} + +// AddCollectorConfigurationSnippet adds a collector configuration snippet to the mock server. +func (lgc *Logic) AddCollectorConfigurationSnippet(id string, snippet *graylog.CollectorConfigurationSnippet) (int, error) { + if id == "" { + return 400, fmt.Errorf("id is required") + } + if err := validator.CreateValidator.Struct(snippet); err != nil { + return 400, err + } + if err := lgc.store.AddCollectorConfigurationSnippet(id, snippet); err != nil { + return 500, err + } + // 202 no content + return 202, nil +} + +// UpdateCollectorConfigurationSnippet updates a collector configuration snippet. +func (lgc *Logic) UpdateCollectorConfigurationSnippet( + cfgID, snippetID string, snippet *graylog.CollectorConfigurationSnippet, +) (int, error) { + if cfgID == "" { + return 400, fmt.Errorf("collector configuration id is required") + } + if snippetID == "" { + return 400, fmt.Errorf("collector configuration snippet id is required") + } + if err := validator.UpdateValidator.Struct(snippet); err != nil { + return 400, err + } + ok, err := lgc.HasCollectorConfigurationSnippet(cfgID, snippetID) + if err != nil { + return 500, err + } + if !ok { + return 404, fmt.Errorf("the collector configuration snippet is not found") + } + + if err := lgc.store.UpdateCollectorConfigurationSnippet(cfgID, snippetID, snippet); err != nil { + return 500, err + } + // 202 no content + return 200, nil +} + +// DeleteCollectorConfigurationSnippet deletes a collector configuration snippet from the mock server. +func (lgc *Logic) DeleteCollectorConfigurationSnippet(cfgID, snippetID string) (int, error) { + ok, err := lgc.HasCollectorConfigurationSnippet(cfgID, snippetID) + if err != nil { + lgc.Logger().WithFields(log.Fields{ + "error": err, "configuration_id": cfgID, + "snippet_id": snippetID, + }).Error("failed to check whether the collector configuration exists") + return 500, err + } + if !ok { + return 404, fmt.Errorf("the collector configuration snippet is not found") + } + if err := lgc.store.DeleteCollectorConfigurationSnippet(cfgID, snippetID); err != nil { + return 500, err + } + return 204, nil +} diff --git a/mockserver/store/plain/collector_configuration.go b/mockserver/store/plain/collector_configuration.go new file mode 100644 index 00000000..5f030bf2 --- /dev/null +++ b/mockserver/store/plain/collector_configuration.go @@ -0,0 +1,77 @@ +package plain + +import ( + "fmt" + + "github.com/suzuki-shunsuke/go-graylog" + st "github.com/suzuki-shunsuke/go-graylog/mockserver/store" +) + +// HasCollectorConfiguration returns whether the collector configuration exists. +func (store *Store) HasCollectorConfiguration(id string) (bool, error) { + store.imutex.RLock() + defer store.imutex.RUnlock() + _, ok := store.collectorConfigurations[id] + return ok, nil +} + +// GetCollectorConfiguration returns an input. +func (store *Store) GetCollectorConfiguration(id string) (*graylog.CollectorConfiguration, error) { + store.imutex.RLock() + defer store.imutex.RUnlock() + s, ok := store.collectorConfigurations[id] + if ok { + return &s, nil + } + return nil, nil +} + +// AddCollectorConfiguration adds a collector configuration to the store. +func (store *Store) AddCollectorConfiguration(cfg *graylog.CollectorConfiguration) error { + if cfg == nil { + return fmt.Errorf("collector configuration is nil") + } + if cfg.ID == "" { + cfg.ID = st.NewObjectID() + } + + store.imutex.Lock() + defer store.imutex.Unlock() + store.collectorConfigurations[cfg.ID] = *cfg + return nil +} + +// RenameCollectorConfiguration renames a collector configuration. +func (store *Store) RenameCollectorConfiguration(id, name string) (*graylog.CollectorConfiguration, error) { + store.imutex.Lock() + defer store.imutex.Unlock() + cfg, ok := store.collectorConfigurations[id] + if !ok { + return nil, fmt.Errorf("the collector configuration <%s> is not found", id) + } + cfg.Name = name + store.collectorConfigurations[id] = cfg + return &cfg, nil +} + +// DeleteCollectorConfiguration deletes a collector configuration from the store. +func (store *Store) DeleteCollectorConfiguration(id string) error { + store.imutex.Lock() + defer store.imutex.Unlock() + delete(store.collectorConfigurations, id) + return nil +} + +// GetCollectorConfigurations returns all collector configurations. +func (store *Store) GetCollectorConfigurations() ([]graylog.CollectorConfiguration, int, error) { + store.imutex.RLock() + defer store.imutex.RUnlock() + size := len(store.collectorConfigurations) + arr := make([]graylog.CollectorConfiguration, size) + i := 0 + for _, cfg := range store.collectorConfigurations { + arr[i] = cfg + i++ + } + return arr, size, nil +} diff --git a/mockserver/store/plain/collector_configuration_input.go b/mockserver/store/plain/collector_configuration_input.go new file mode 100644 index 00000000..4266b53f --- /dev/null +++ b/mockserver/store/plain/collector_configuration_input.go @@ -0,0 +1,99 @@ +package plain + +import ( + "fmt" + + "github.com/suzuki-shunsuke/go-graylog" + st "github.com/suzuki-shunsuke/go-graylog/mockserver/store" +) + +// HasCollectorConfigurationInput returns whether the collector configuration input exists. +func (store *Store) HasCollectorConfigurationInput(cfgID, inputID string) (bool, error) { + store.imutex.RLock() + defer store.imutex.RUnlock() + cfg, ok := store.collectorConfigurations[cfgID] + if !ok { + return false, nil + } + for _, input := range cfg.Inputs { + if input.InputID == inputID { + return true, nil + } + } + return false, nil +} + +// AddCollectorConfigurationInput adds a collector configuration input to the store. +func (store *Store) AddCollectorConfigurationInput(cfgID string, input *graylog.CollectorConfigurationInput) error { + if cfgID == "" { + return fmt.Errorf("id is required") + } + if input == nil { + return fmt.Errorf("collector configuration input is nil") + } + if input.InputID == "" { + input.InputID = st.NewObjectID() + } + + store.imutex.Lock() + defer store.imutex.Unlock() + cfg, ok := store.collectorConfigurations[cfgID] + if !ok { + return fmt.Errorf("collector configuration <%s> is not found", cfgID) + } + cfg.Inputs = append(cfg.Inputs, *input) + store.collectorConfigurations[cfgID] = cfg + return nil +} + +// UpdateCollectorConfigurationInput updates a collector configuration input. +func (store *Store) UpdateCollectorConfigurationInput(cfgID, inputID string, input *graylog.CollectorConfigurationInput) error { + if cfgID == "" { + return fmt.Errorf("collector configuration id is required") + } + if inputID == "" { + return fmt.Errorf("collector configuration input id is required") + } + if input == nil { + return fmt.Errorf("collector configuration input is nil") + } + store.imutex.Lock() + defer store.imutex.Unlock() + cfg, ok := store.collectorConfigurations[cfgID] + if !ok { + return fmt.Errorf("the collector configuration <%s> is not found", cfgID) + } + for i, a := range cfg.Inputs { + if a.InputID == inputID { + cfg.Inputs[i] = *input + store.collectorConfigurations[cfgID] = cfg + return nil + } + } + return fmt.Errorf("collector configuration input is not found") +} + +// DeleteCollectorConfigurationInput deletes a collector configuration input from the store. +func (store *Store) DeleteCollectorConfigurationInput(cfgID, inputID string) error { + store.imutex.Lock() + defer store.imutex.Unlock() + cfg, ok := store.collectorConfigurations[cfgID] + if !ok { + return fmt.Errorf("the collector configuration <%s> is not found", cfgID) + } + inputs := []graylog.CollectorConfigurationInput{} + removed := false + for _, a := range cfg.Inputs { + if a.InputID == inputID { + removed = true + continue + } + inputs = append(inputs, a) + } + if !removed { + return fmt.Errorf("the collector configuration input is not found") + } + cfg.Inputs = inputs + store.collectorConfigurations[cfgID] = cfg + return nil +} diff --git a/mockserver/store/plain/collector_configuration_output.go b/mockserver/store/plain/collector_configuration_output.go new file mode 100644 index 00000000..167e349e --- /dev/null +++ b/mockserver/store/plain/collector_configuration_output.go @@ -0,0 +1,99 @@ +package plain + +import ( + "fmt" + + "github.com/suzuki-shunsuke/go-graylog" + st "github.com/suzuki-shunsuke/go-graylog/mockserver/store" +) + +// HasCollectorConfigurationOutput returns whether the collector configuration output exists. +func (store *Store) HasCollectorConfigurationOutput(cfgID, outputID string) (bool, error) { + store.imutex.RLock() + defer store.imutex.RUnlock() + cfg, ok := store.collectorConfigurations[cfgID] + if !ok { + return false, nil + } + for _, output := range cfg.Outputs { + if output.OutputID == outputID { + return true, nil + } + } + return false, nil +} + +// AddCollectorConfigurationOutput adds a collector configuration output to the store. +func (store *Store) AddCollectorConfigurationOutput(cfgID string, output *graylog.CollectorConfigurationOutput) error { + if cfgID == "" { + return fmt.Errorf("id is required") + } + if output == nil { + return fmt.Errorf("collector configuration output is nil") + } + if output.OutputID == "" { + output.OutputID = st.NewObjectID() + } + + store.imutex.Lock() + defer store.imutex.Unlock() + cfg, ok := store.collectorConfigurations[cfgID] + if !ok { + return fmt.Errorf("collector configuration <%s> is not found", cfgID) + } + cfg.Outputs = append(cfg.Outputs, *output) + store.collectorConfigurations[cfgID] = cfg + return nil +} + +// UpdateCollectorConfigurationOutput updates a collector configuration output. +func (store *Store) UpdateCollectorConfigurationOutput(cfgID, outputID string, output *graylog.CollectorConfigurationOutput) error { + if cfgID == "" { + return fmt.Errorf("collector configuration id is required") + } + if outputID == "" { + return fmt.Errorf("collector configuration output id is required") + } + if output == nil { + return fmt.Errorf("collector configuration output is nil") + } + store.imutex.Lock() + defer store.imutex.Unlock() + cfg, ok := store.collectorConfigurations[cfgID] + if !ok { + return fmt.Errorf("the collector configuration <%s> is not found", cfgID) + } + for i, a := range cfg.Outputs { + if a.OutputID == outputID { + cfg.Outputs[i] = *output + store.collectorConfigurations[cfgID] = cfg + return nil + } + } + return fmt.Errorf("collector configuration output is not found") +} + +// DeleteCollectorConfigurationOutput deletes a collector configuration output from the store. +func (store *Store) DeleteCollectorConfigurationOutput(cfgID, outputID string) error { + store.imutex.Lock() + defer store.imutex.Unlock() + cfg, ok := store.collectorConfigurations[cfgID] + if !ok { + return fmt.Errorf("the collector configuration <%s> is not found", cfgID) + } + outputs := []graylog.CollectorConfigurationOutput{} + removed := false + for _, a := range cfg.Outputs { + if a.OutputID == outputID { + removed = true + continue + } + outputs = append(outputs, a) + } + if !removed { + return fmt.Errorf("the collector configuration output is not found") + } + cfg.Outputs = outputs + store.collectorConfigurations[cfgID] = cfg + return nil +} diff --git a/mockserver/store/plain/collector_configuration_snippet.go b/mockserver/store/plain/collector_configuration_snippet.go new file mode 100644 index 00000000..af8813c0 --- /dev/null +++ b/mockserver/store/plain/collector_configuration_snippet.go @@ -0,0 +1,99 @@ +package plain + +import ( + "fmt" + + "github.com/suzuki-shunsuke/go-graylog" + st "github.com/suzuki-shunsuke/go-graylog/mockserver/store" +) + +// HasCollectorConfigurationSnippet returns whether the collector configuration snippet exists. +func (store *Store) HasCollectorConfigurationSnippet(cfgID, snippetID string) (bool, error) { + store.imutex.RLock() + defer store.imutex.RUnlock() + cfg, ok := store.collectorConfigurations[cfgID] + if !ok { + return false, nil + } + for _, snippet := range cfg.Snippets { + if snippet.SnippetID == snippetID { + return true, nil + } + } + return false, nil +} + +// AddCollectorConfigurationSnippet adds a collector configuration snippet to the store. +func (store *Store) AddCollectorConfigurationSnippet(cfgID string, snippet *graylog.CollectorConfigurationSnippet) error { + if cfgID == "" { + return fmt.Errorf("id is required") + } + if snippet == nil { + return fmt.Errorf("collector configuration snippet is nil") + } + if snippet.SnippetID == "" { + snippet.SnippetID = st.NewObjectID() + } + + store.imutex.Lock() + defer store.imutex.Unlock() + cfg, ok := store.collectorConfigurations[cfgID] + if !ok { + return fmt.Errorf("collector configuration <%s> is not found", cfgID) + } + cfg.Snippets = append(cfg.Snippets, *snippet) + store.collectorConfigurations[cfgID] = cfg + return nil +} + +// UpdateCollectorConfigurationSnippet updates a collector configuration snippet. +func (store *Store) UpdateCollectorConfigurationSnippet(cfgID, snippetID string, snippet *graylog.CollectorConfigurationSnippet) error { + if cfgID == "" { + return fmt.Errorf("collector configuration id is required") + } + if snippetID == "" { + return fmt.Errorf("collector configuration snippet id is required") + } + if snippet == nil { + return fmt.Errorf("collector configuration snippet is nil") + } + store.imutex.Lock() + defer store.imutex.Unlock() + cfg, ok := store.collectorConfigurations[cfgID] + if !ok { + return fmt.Errorf("the collector configuration <%s> is not found", cfgID) + } + for i, a := range cfg.Snippets { + if a.SnippetID == snippetID { + cfg.Snippets[i] = *snippet + store.collectorConfigurations[cfgID] = cfg + return nil + } + } + return fmt.Errorf("collector configuration snippet is not found") +} + +// DeleteCollectorConfigurationSnippet deletes a collector configuration snippet from the store. +func (store *Store) DeleteCollectorConfigurationSnippet(cfgID, snippetID string) error { + store.imutex.Lock() + defer store.imutex.Unlock() + cfg, ok := store.collectorConfigurations[cfgID] + if !ok { + return fmt.Errorf("the collector configuration <%s> is not found", cfgID) + } + snippets := []graylog.CollectorConfigurationSnippet{} + removed := false + for _, a := range cfg.Snippets { + if a.SnippetID == snippetID { + removed = true + continue + } + snippets = append(snippets, a) + } + if !removed { + return fmt.Errorf("the collector configuration snippet is not found") + } + cfg.Snippets = snippets + store.collectorConfigurations[cfgID] = cfg + return nil +} diff --git a/mockserver/store/plain/store.go b/mockserver/store/plain/store.go index 53c7c57b..134a145e 100644 --- a/mockserver/store/plain/store.go +++ b/mockserver/store/plain/store.go @@ -13,16 +13,17 @@ import ( // Store is the implementation of the Store interface with pure golang. type Store struct { - alarmCallbacks map[string]graylog.AlarmCallback - alerts map[string]graylog.Alert - alertConditions map[string]graylog.AlertCondition - dashboards map[string]graylog.Dashboard - indexSets []graylog.IndexSet - inputs map[string]graylog.Input - roles map[string]graylog.Role - streams map[string]graylog.Stream - users map[string]graylog.User - ldapSetting *graylog.LDAPSetting + alarmCallbacks map[string]graylog.AlarmCallback + alerts map[string]graylog.Alert + alertConditions map[string]graylog.AlertCondition + collectorConfigurations map[string]graylog.CollectorConfiguration + dashboards map[string]graylog.Dashboard + indexSets []graylog.IndexSet + inputs map[string]graylog.Input + roles map[string]graylog.Role + streams map[string]graylog.Stream + users map[string]graylog.User + ldapSetting *graylog.LDAPSetting tokens map[string]string @@ -33,16 +34,17 @@ type Store struct { } type plainStore struct { - AlarmCallbacks map[string]graylog.AlarmCallback `json:"alarm_callbacks"` - Alerts map[string]graylog.Alert `json:"alerts"` - AlertConditions map[string]graylog.AlertCondition `json:"alert_conditions"` - Dashboards map[string]graylog.Dashboard `json:"dashboards"` - Inputs map[string]graylog.Input `json:"inputs"` - IndexSets []graylog.IndexSet `json:"index_sets"` - Roles map[string]graylog.Role `json:"roles"` - Streams map[string]graylog.Stream `json:"streams"` - Users map[string]graylog.User `json:"users"` - LDAPSetting *graylog.LDAPSetting `json:"ldap_setting"` + AlarmCallbacks map[string]graylog.AlarmCallback `json:"alarm_callbacks"` + Alerts map[string]graylog.Alert `json:"alerts"` + AlertConditions map[string]graylog.AlertCondition `json:"alert_conditions"` + CollectorConfigurations map[string]graylog.CollectorConfiguration `json:"collector_configurations"` + Dashboards map[string]graylog.Dashboard `json:"dashboards"` + Inputs map[string]graylog.Input `json:"inputs"` + IndexSets []graylog.IndexSet `json:"index_sets"` + Roles map[string]graylog.Role `json:"roles"` + Streams map[string]graylog.Stream `json:"streams"` + Users map[string]graylog.User `json:"users"` + LDAPSetting *graylog.LDAPSetting `json:"ldap_setting"` Tokens map[string]string `json:"tokens"` @@ -52,15 +54,17 @@ type plainStore struct { // MarshalJSON is the implementation of the json.Marshaler interface. func (store *Store) MarshalJSON() ([]byte, error) { data := map[string]interface{}{ - "alarm_callbacks": store.alarmCallbacks, - "alerts": store.alerts, - "alert_conditions": store.alertConditions, - "inputs": store.inputs, - "index_sets": store.indexSets, - "roles": store.roles, - "streams": store.streams, - "users": store.users, - "ldap_setting": store.ldapSetting, + "alarm_callbacks": store.alarmCallbacks, + "alerts": store.alerts, + "alert_conditions": store.alertConditions, + "collector_configurations": store.collectorConfigurations, + "dashboards": store.dashboards, + "inputs": store.inputs, + "index_sets": store.indexSets, + "roles": store.roles, + "streams": store.streams, + "users": store.users, + "ldap_setting": store.ldapSetting, "tokens": store.tokens, @@ -78,6 +82,7 @@ func (store *Store) UnmarshalJSON(b []byte) error { store.alarmCallbacks = s.AlarmCallbacks store.alerts = s.Alerts store.alertConditions = s.AlertConditions + store.collectorConfigurations = s.CollectorConfigurations store.dashboards = s.Dashboards store.inputs = s.Inputs store.indexSets = s.IndexSets @@ -97,16 +102,17 @@ func (store *Store) UnmarshalJSON(b []byte) error { // If `dataPath` is empty, the data aren't written to the file. func NewStore(dataPath string) store.Store { return &Store{ - alarmCallbacks: map[string]graylog.AlarmCallback{}, - alerts: map[string]graylog.Alert{}, - alertConditions: map[string]graylog.AlertCondition{}, - dashboards: map[string]graylog.Dashboard{}, - inputs: map[string]graylog.Input{}, - indexSets: []graylog.IndexSet{}, - roles: map[string]graylog.Role{}, - streams: map[string]graylog.Stream{}, - users: map[string]graylog.User{}, - ldapSetting: defaultLDAPSetting(), + alarmCallbacks: map[string]graylog.AlarmCallback{}, + alerts: map[string]graylog.Alert{}, + alertConditions: map[string]graylog.AlertCondition{}, + collectorConfigurations: map[string]graylog.CollectorConfiguration{}, + dashboards: map[string]graylog.Dashboard{}, + inputs: map[string]graylog.Input{}, + indexSets: []graylog.IndexSet{}, + roles: map[string]graylog.Role{}, + streams: map[string]graylog.Stream{}, + users: map[string]graylog.User{}, + ldapSetting: defaultLDAPSetting(), tokens: map[string]string{}, diff --git a/mockserver/store/store.go b/mockserver/store/store.go index 2eaf8d18..b5208b77 100644 --- a/mockserver/store/store.go +++ b/mockserver/store/store.go @@ -35,6 +35,28 @@ type Store interface { DeleteInput(id string) error HasInput(id string) (bool, error) + HasCollectorConfiguration(id string) (bool, error) + DeleteCollectorConfiguration(id string) error + AddCollectorConfiguration(*graylog.CollectorConfiguration) error + RenameCollectorConfiguration(id, name string) (*graylog.CollectorConfiguration, error) + GetCollectorConfiguration(id string) (*graylog.CollectorConfiguration, error) + GetCollectorConfigurations() ([]graylog.CollectorConfiguration, int, error) + + HasCollectorConfigurationInput(cfgID, inputID string) (bool, error) + AddCollectorConfigurationInput(cfgID string, input *graylog.CollectorConfigurationInput) error + UpdateCollectorConfigurationInput(cfgID, inputID string, input *graylog.CollectorConfigurationInput) error + DeleteCollectorConfigurationInput(cfgID, inputID string) error + + HasCollectorConfigurationOutput(cfgID, outputID string) (bool, error) + AddCollectorConfigurationOutput(cfgID string, output *graylog.CollectorConfigurationOutput) error + UpdateCollectorConfigurationOutput(cfgID, outputID string, output *graylog.CollectorConfigurationOutput) error + DeleteCollectorConfigurationOutput(cfgID, outputID string) error + + HasCollectorConfigurationSnippet(cfgID, snippetID string) (bool, error) + AddCollectorConfigurationSnippet(cfgID string, snippet *graylog.CollectorConfigurationSnippet) error + UpdateCollectorConfigurationSnippet(cfgID, snippetID string, snippet *graylog.CollectorConfigurationSnippet) error + DeleteCollectorConfigurationSnippet(cfgID, snippetID string) error + AddIndexSet(*graylog.IndexSet) error GetIndexSet(id string) (*graylog.IndexSet, error) GetIndexSets(skip, limit int) ([]graylog.IndexSet, int, error) diff --git a/terraform/README.md b/terraform/README.md index 691d084c..01573534 100644 --- a/terraform/README.md +++ b/terraform/README.md @@ -67,3 +67,17 @@ auth_password | GRAYLOG_AUTH_PASSWORD | * [stream](docs/stream.md) * [user](docs/user.md) * [ldap_setting](docs/ldap_setting.md) + +## Unsupported resources + +We can't support these resources for some reasons. + +### CollectorConfiguration (includes input, output snippet) + +We can't support these resources because graylog API doesn't return the created resource id (response body: no content). + +The following APIs doesn't return the created resource id (response body: no content). + +* POST /plugins/org.graylog.plugins.collector/configurations/{id}/inputs Create a configuration input +* POST /plugins/org.graylog.plugins.collector/configurations/{id}/outputs Create a configuration output +* POST /plugins/org.graylog.plugins.collector/configurations/{id}/snippets Create a configuration snippet