From 89b600bdb5882f855b264709612ca234256c935c Mon Sep 17 00:00:00 2001 From: Anna Lushnikova Date: Mon, 7 Oct 2024 11:26:07 -0400 Subject: [PATCH 1/7] [databases]: update structs for logsinks by sink type --- databases.go | 275 ++++++++++++++++++++++++++------- databases_test.go | 380 +++++++++++++++++++++++----------------------- 2 files changed, 412 insertions(+), 243 deletions(-) diff --git a/databases.go b/databases.go index 276fb4a..ce1d86c 100644 --- a/databases.go +++ b/databases.go @@ -174,10 +174,16 @@ type DatabasesService interface { ListDatabaseEvents(context.Context, string, *ListOptions) ([]DatabaseEvent, *Response, error) ListIndexes(context.Context, string, *ListOptions) ([]DatabaseIndex, *Response, error) DeleteIndex(context.Context, string, string) (*Response, error) - CreateLogsink(ctx context.Context, databaseID string, createLogsink *DatabaseCreateLogsinkRequest) (*DatabaseLogsink, *Response, error) - GetLogsink(ctx context.Context, databaseID string, logsinkID string) (*DatabaseLogsink, *Response, error) - ListLogsinks(ctx context.Context, databaseID string, opts *ListOptions) ([]DatabaseLogsink, *Response, error) - UpdateLogsink(ctx context.Context, databaseID string, logsinkID string, updateLogsink *DatabaseUpdateLogsinkRequest) (*Response, error) + GetRsyslogLogsink(ctx context.Context, databaseID string, logsinkID string) (*DatabaseRsyslogLogsink, *Response, error) + CreateRsyslogLogsink(ctx context.Context, databaseID string, createLogsink *DatabaseCreateRsyslogLogsinkRequest) (*DatabaseRsyslogLogsink, *Response, error) + UpdateRsyslogLogsink(ctx context.Context, databaseID string, logsinkID string, updateLogsink *DatabaseUpdateRsyslogLogsinkRequest) (*Response, error) + GetElasticsearchLogsink(ctx context.Context, databaseID string, logsinkID string) (*DatabaseElasticsearchLogsink, *Response, error) + CreateElasticsearchLogsink(ctx context.Context, databaseID string, createLogsink *DatabaseCreateElasticsearchLogsinkRequest) (*DatabaseElasticsearchLogsink, *Response, error) + UpdateElasticsearchLogsink(ctx context.Context, databaseID string, logsinkID string, updateLogsink *DatabaseUpdateElasticsearchLogsinkRequest) (*Response, error) + GetOpensearchLogsink(ctx context.Context, databaseID string, logsinkID string) (*DatabaseOpensearchLogsink, *Response, error) + CreateOpensearchLogsink(ctx context.Context, databaseID string, createLogsink *DatabaseCreateOpensearchLogsinkRequest) (*DatabaseOpensearchLogsink, *Response, error) + UpdateOpensearchLogsink(ctx context.Context, databaseID string, logsinkID string, updateLogsink *DatabaseUpdateOpensearchLogsinkRequest) (*Response, error) + ListLogsinks(ctx context.Context, databaseID string, opts *ListOptions) ([]interface{}, *Response, error) DeleteLogsink(ctx context.Context, databaseID, logsinkID string) (*Response, error) } @@ -350,14 +356,6 @@ type DatabaseTopic struct { Config *TopicConfig `json:"config,omitempty"` } -// DatabaseLogsink represents a logsink -type DatabaseLogsink struct { - ID string `json:"sink_id"` - Name string `json:"sink_name,omitempty"` - Type string `json:"sink_type,omitempty"` - Config *DatabaseLogsinkConfig `json:"config,omitempty"` -} - // TopicPartition represents the state of a Kafka topic partition type TopicPartition struct { EarliestOffset uint64 `json:"earliest_offset,omitempty"` @@ -507,33 +505,95 @@ type DatabaseFirewallRule struct { CreatedAt time.Time `json:"created_at"` } -// DatabaseCreateLogsinkRequest is used to create logsink for a database cluster -type DatabaseCreateLogsinkRequest struct { - Name string `json:"sink_name"` - Type string `json:"sink_type"` - Config *DatabaseLogsinkConfig `json:"config"` +// DatabaseRsyslogLogsink represents a rsyslog logsink. +type DatabaseRsyslogLogsink struct { + ID string `json:"sink_id"` + Name string `json:"sink_name,required"` + Type string `json:"sink_type,required"` + Config *RsyslogLogsinkConfig `json:"config,required"` +} + +// DatabaseCreateRsyslogLogsinkRequest is used to create rsyslog logsink for a database cluster. +type DatabaseCreateRsyslogLogsinkRequest struct { + Name string `json:"sink_name"` + Type string `json:"sink_type"` + Config *RsyslogLogsinkConfig `json:"config"` +} + +// DatabaseUpdateRsyslogLogsinkRequest is used to update rsyslog logsink for a database cluster. +type DatabaseUpdateRsyslogLogsinkRequest struct { + Config *RsyslogLogsinkConfig `json:"config"` +} + +// RsyslogLogsinkConfig represents rsyslog logsink configuration. +type RsyslogLogsinkConfig struct { + Server string `json:"server,required"` + Port int `json:"port,required"` + TLS bool `json:"tls,required"` + Format string `json:"format,required"` + Logline string `json:"logline,omitempty"` + SD string `json:"sd,omitempty"` + CA string `json:"ca,omitempty"` + Key string `json:"key,omitempty"` + Cert string `json:"cert,omitempty"` } -// DatabaseUpdateLogsinkRequest is used to update logsink for a database cluster -type DatabaseUpdateLogsinkRequest struct { - Config *DatabaseLogsinkConfig `json:"config"` +// DatabaseElasticsearchLogsink represents an elasticsearch logsink. +type DatabaseElasticsearchLogsink struct { + ID string `json:"sink_id"` + Name string `json:"sink_name,required"` + Type string `json:"sink_type,required"` + Config *ElasticsearchLogsinkConfig `json:"config,required"` } -// DatabaseLogsinkConfig represents one of the configurable options (rsyslog_logsink, elasticsearch_logsink, or opensearch_logsink) for a logsink. -type DatabaseLogsinkConfig struct { - URL string `json:"url,omitempty"` - IndexPrefix string `json:"index_prefix,omitempty"` +// DatabaseCreateElasticsearchLogsinkRequest is used to create elasticsearch logsink for a database cluster. +type DatabaseCreateElasticsearchLogsinkRequest struct { + Name string `json:"sink_name"` + Type string `json:"sink_type"` + Config *ElasticsearchLogsinkConfig `json:"config"` +} + +// DatabaseUpdateElasticsearchLogsinkRequest is used to update elasticsearch logsink for a database cluster. +type DatabaseUpdateElasticsearchLogsinkRequest struct { + Config *ElasticsearchLogsinkConfig `json:"config"` +} + +// ElasticsearchLogsinkConfig represents elasticsearch logsink configuration. +type ElasticsearchLogsinkConfig struct { + URL string `json:"url,required"` + IndexPrefix string `json:"index_prefix,required"` + IndexDaysMax int `json:"index_days_max,omitempty"` + Timeout float32 `json:"timeout,omitempty"` + CA string `json:"ca,omitempty"` +} + +// DatabaseOpensearchLogsink represents an opensearch logsink. +type DatabaseOpensearchLogsink struct { + ID string `json:"sink_id"` + Name string `json:"sink_name,required"` + Type string `json:"sink_type,required"` + Config *OpensearchLogsinkConfig `json:"config,required"` +} + +// DatabaseCreateOpensearchLogsinkRequest is used to create opensearch logsink for a database cluster. +type DatabaseCreateOpensearchLogsinkRequest struct { + Name string `json:"sink_name"` + Type string `json:"sink_type"` + Config *OpensearchLogsinkConfig `json:"config"` +} + +// DatabaseUpdateOpensearchLogsinkRequest is used to update opensearch logsink for a database cluster. +type DatabaseUpdateOpensearchLogsinkRequest struct { + Config *OpensearchLogsinkConfig `json:"config"` +} + +// OpensearchLogsinkConfig represents opensearch logsink configuration. +type OpensearchLogsinkConfig struct { + URL string `json:"url,required"` + IndexPrefix string `json:"index_prefix,required"` IndexDaysMax int `json:"index_days_max,omitempty"` Timeout float32 `json:"timeout,omitempty"` - Server string `json:"server,omitempty"` - Port int `json:"port,omitempty"` - TLS bool `json:"tls,omitempty"` - Format string `json:"format,omitempty"` - Logline string `json:"logline,omitempty"` - SD string `json:"sd,omitempty"` CA string `json:"ca,omitempty"` - Key string `json:"key,omitempty"` - Cert string `json:"cert,omitempty"` } // PostgreSQLConfig holds advanced configurations for PostgreSQL database clusters. @@ -828,8 +888,20 @@ type databaseTopicsRoot struct { Topics []DatabaseTopic `json:"topics"` } +type databaseRsyslogLogsinkRoot struct { + Sink DatabaseRsyslogLogsink `json:"sink"` +} + +type databaseElasticsearchLogsinkRoot struct { + Sink DatabaseElasticsearchLogsink `json:"sink"` +} + +type databaseOpensearchLogsinkRoot struct { + Sink DatabaseOpensearchLogsink `json:"sink"` +} + type databaseLogsinksRoot struct { - Sinks []DatabaseLogsink `json:"sinks"` + Sinks []interface{} `json:"sinks"` } type databaseMetricsCredentialsRoot struct { @@ -1878,59 +1950,122 @@ func (svc *DatabasesServiceOp) DeleteIndex(ctx context.Context, databaseID, name return resp, nil } -// CreateLogsink creates a new logsink for a database -func (svc *DatabasesServiceOp) CreateLogsink(ctx context.Context, databaseID string, createLogsink *DatabaseCreateLogsinkRequest) (*DatabaseLogsink, *Response, error) { +// ListTopics returns all topics for a given kafka cluster. +func (svc *DatabasesServiceOp) ListLogsinks(ctx context.Context, databaseID string, opts *ListOptions) ([]interface{}, *Response, error) { path := fmt.Sprintf(databaseLogsinksPath, databaseID) - req, err := svc.client.NewRequest(ctx, http.MethodPost, path, createLogsink) + path, err := addOptions(path, opts) if err != nil { return nil, nil, err } - - root := new(DatabaseLogsink) + req, err := svc.client.NewRequest(ctx, http.MethodGet, path, nil) + if err != nil { + return nil, nil, err + } + root := new(databaseLogsinksRoot) resp, err := svc.client.Do(ctx, req, root) if err != nil { return nil, resp, err } - return root, resp, nil + return root.Sinks, resp, nil +} + +// DeleteLogsink deletes a logsink for a database cluster. +func (svc *DatabasesServiceOp) DeleteLogsink(ctx context.Context, databaseID, logsinkID string) (*Response, error) { + path := fmt.Sprintf(databaseLogsinkPath, databaseID, logsinkID) + req, err := svc.client.NewRequest(ctx, http.MethodDelete, path, nil) + if err != nil { + return nil, err + } + resp, err := svc.client.Do(ctx, req, nil) + if err != nil { + return resp, err + } + return resp, nil } -// GetLogsink gets a logsink for a database -func (svc *DatabasesServiceOp) GetLogsink(ctx context.Context, databaseID string, logsinkID string) (*DatabaseLogsink, *Response, error) { +// GetRsyslogLogsink gets a logsink for a database. +func (svc *DatabasesServiceOp) GetRsyslogLogsink(ctx context.Context, databaseID string, logsinkID string) (*DatabaseRsyslogLogsink, *Response, error) { path := fmt.Sprintf(databaseLogsinkPath, databaseID, logsinkID) req, err := svc.client.NewRequest(ctx, http.MethodGet, path, nil) if err != nil { return nil, nil, err } - root := new(DatabaseLogsink) + root := new(databaseRsyslogLogsinkRoot) resp, err := svc.client.Do(ctx, req, root) if err != nil { return nil, resp, err } - return root, resp, nil + return &root.Sink, resp, nil } -// ListTopics returns all topics for a given kafka cluster -func (svc *DatabasesServiceOp) ListLogsinks(ctx context.Context, databaseID string, opts *ListOptions) ([]DatabaseLogsink, *Response, error) { +// CreateRsyslogLogsink creates a new logsink for a database. +func (svc *DatabasesServiceOp) CreateRsyslogLogsink(ctx context.Context, databaseID string, createLogsink *DatabaseCreateRsyslogLogsinkRequest) (*DatabaseRsyslogLogsink, *Response, error) { path := fmt.Sprintf(databaseLogsinksPath, databaseID) - path, err := addOptions(path, opts) + req, err := svc.client.NewRequest(ctx, http.MethodPost, path, createLogsink) if err != nil { return nil, nil, err } + + root := new(databaseRsyslogLogsinkRoot) + resp, err := svc.client.Do(ctx, req, root) + if err != nil { + return nil, resp, err + } + + return &root.Sink, resp, nil +} + +// UpdateRsyslogLogsink updates a logsink for a database cluster. +func (svc *DatabasesServiceOp) UpdateRsyslogLogsink(ctx context.Context, databaseID string, logsinkID string, updateLogsink *DatabaseUpdateRsyslogLogsinkRequest) (*Response, error) { + path := fmt.Sprintf(databaseLogsinkPath, databaseID, logsinkID) + req, err := svc.client.NewRequest(ctx, http.MethodPut, path, updateLogsink) + if err != nil { + return nil, err + } + + resp, err := svc.client.Do(ctx, req, nil) + if err != nil { + return resp, err + } + return resp, nil +} + +// GetElasticsearchLogsink gets a logsink for a database. +func (svc *DatabasesServiceOp) GetElasticsearchLogsink(ctx context.Context, databaseID string, logsinkID string) (*DatabaseElasticsearchLogsink, *Response, error) { + path := fmt.Sprintf(databaseLogsinkPath, databaseID, logsinkID) req, err := svc.client.NewRequest(ctx, http.MethodGet, path, nil) if err != nil { return nil, nil, err } - root := new(databaseLogsinksRoot) + + root := new(databaseElasticsearchLogsinkRoot) resp, err := svc.client.Do(ctx, req, root) if err != nil { return nil, resp, err } - return root.Sinks, resp, nil + return &root.Sink, resp, nil +} + +// CreateElasticsearchLogsink creates a new logsink for a database. +func (svc *DatabasesServiceOp) CreateElasticsearchLogsink(ctx context.Context, databaseID string, createLogsink *DatabaseCreateElasticsearchLogsinkRequest) (*DatabaseElasticsearchLogsink, *Response, error) { + path := fmt.Sprintf(databaseLogsinksPath, databaseID) + req, err := svc.client.NewRequest(ctx, http.MethodPost, path, createLogsink) + if err != nil { + return nil, nil, err + } + + root := new(databaseElasticsearchLogsinkRoot) + resp, err := svc.client.Do(ctx, req, root) + if err != nil { + return nil, resp, err + } + + return &root.Sink, resp, nil } -// UpdateLogsink updates a logsink for a database cluster -func (svc *DatabasesServiceOp) UpdateLogsink(ctx context.Context, databaseID string, logsinkID string, updateLogsink *DatabaseUpdateLogsinkRequest) (*Response, error) { +// UpdateElasticsearchLogsink updates a logsink for a database cluster. +func (svc *DatabasesServiceOp) UpdateElasticsearchLogsink(ctx context.Context, databaseID string, logsinkID string, updateLogsink *DatabaseUpdateElasticsearchLogsinkRequest) (*Response, error) { path := fmt.Sprintf(databaseLogsinkPath, databaseID, logsinkID) req, err := svc.client.NewRequest(ctx, http.MethodPut, path, updateLogsink) if err != nil { @@ -1944,13 +2079,47 @@ func (svc *DatabasesServiceOp) UpdateLogsink(ctx context.Context, databaseID str return resp, nil } -// DeleteLogsink deletes a logsink for a database cluster -func (svc *DatabasesServiceOp) DeleteLogsink(ctx context.Context, databaseID, logsinkID string) (*Response, error) { +// GetOpensearchLogsink gets a logsink for a database. +func (svc *DatabasesServiceOp) GetOpensearchLogsink(ctx context.Context, databaseID string, logsinkID string) (*DatabaseOpensearchLogsink, *Response, error) { path := fmt.Sprintf(databaseLogsinkPath, databaseID, logsinkID) - req, err := svc.client.NewRequest(ctx, http.MethodDelete, path, nil) + req, err := svc.client.NewRequest(ctx, http.MethodGet, path, nil) + if err != nil { + return nil, nil, err + } + + root := new(databaseOpensearchLogsinkRoot) + resp, err := svc.client.Do(ctx, req, root) + if err != nil { + return nil, resp, err + } + return &root.Sink, resp, nil +} + +// CreateOpensearchLogsink creates a new logsink for a database. +func (svc *DatabasesServiceOp) CreateOpensearchLogsink(ctx context.Context, databaseID string, createLogsink *DatabaseCreateOpensearchLogsinkRequest) (*DatabaseOpensearchLogsink, *Response, error) { + path := fmt.Sprintf(databaseLogsinksPath, databaseID) + req, err := svc.client.NewRequest(ctx, http.MethodPost, path, createLogsink) + if err != nil { + return nil, nil, err + } + + root := new(databaseOpensearchLogsinkRoot) + resp, err := svc.client.Do(ctx, req, root) + if err != nil { + return nil, resp, err + } + + return &root.Sink, resp, nil +} + +// UpdateOpensearchLogsink updates a logsink for a database cluster. +func (svc *DatabasesServiceOp) UpdateOpensearchLogsink(ctx context.Context, databaseID string, logsinkID string, updateLogsink *DatabaseUpdateOpensearchLogsinkRequest) (*Response, error) { + path := fmt.Sprintf(databaseLogsinkPath, databaseID, logsinkID) + req, err := svc.client.NewRequest(ctx, http.MethodPut, path, updateLogsink) if err != nil { return nil, err } + resp, err := svc.client.Do(ctx, req, nil) if err != nil { return resp, err diff --git a/databases_test.go b/databases_test.go index 96d16ea..7f65649 100644 --- a/databases_test.go +++ b/databases_test.go @@ -3834,196 +3834,196 @@ func TestDatabases_DeleteIndexes(t *testing.T) { require.NoError(t, err) } -func TestDatabases_CreateLogsink(t *testing.T) { - setup() - defer teardown() - - var ( - dbID = "deadbeef-dead-4aa5-beef-deadbeef347d" - ) - - want := &DatabaseLogsink{ - ID: "deadbeef-dead-4aa5-beef-deadbeef347d", - Name: "logs-sink", - Type: "opensearch", - Config: &DatabaseLogsinkConfig{ - URL: "https://user:passwd@192.168.0.1:25060", - IndexPrefix: "opensearch-logs", - }, - } - - body := `{ - "sink_id":"deadbeef-dead-4aa5-beef-deadbeef347d", - "sink_name": "logs-sink", - "sink_type": "opensearch", - "config": { - "url": "https://user:passwd@192.168.0.1:25060", - "index_prefix": "opensearch-logs" - } - }` - - path := fmt.Sprintf("/v2/databases/%s/logsink", dbID) - - mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, http.MethodPost) - fmt.Fprint(w, body) - }) - - log, _, err := client.Databases.CreateLogsink(ctx, dbID, &DatabaseCreateLogsinkRequest{ - Name: "logs-sink", - Type: "opensearch", - Config: &DatabaseLogsinkConfig{ - URL: "https://user:passwd@192.168.0.1:25060", - IndexPrefix: "opensearch-logs", - }, - }) - - require.NoError(t, err) - - require.Equal(t, want, log) -} - -func TestDatabases_GetLogsink(t *testing.T) { - setup() - defer teardown() - - var ( - dbID = "deadbeef-dead-4aa5-beef-deadbeef347d" - logsinkID = "50484ec3-19d6-4cd3-b56f-3b0381c289a6" - ) - - want := &DatabaseLogsink{ - ID: "deadbeef-dead-4aa5-beef-deadbeef347d", - Name: "logs-sink", - Type: "opensearch", - Config: &DatabaseLogsinkConfig{ - URL: "https://user:passwd@192.168.0.1:25060", - IndexPrefix: "opensearch-logs", - }, - } - - body := `{ - "sink_id":"deadbeef-dead-4aa5-beef-deadbeef347d", - "sink_name": "logs-sink", - "sink_type": "opensearch", - "config": { - "url": "https://user:passwd@192.168.0.1:25060", - "index_prefix": "opensearch-logs" - } - }` - - path := fmt.Sprintf("/v2/databases/%s/logsink/%s", dbID, logsinkID) - - mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, http.MethodGet) - fmt.Fprint(w, body) - }) - - got, _, err := client.Databases.GetLogsink(ctx, dbID, logsinkID) - require.NoError(t, err) - require.Equal(t, want, got) -} - -func TestDatabases_UpdateLogsink(t *testing.T) { - setup() - defer teardown() - - var ( - dbID = "deadbeef-dead-4aa5-beef-deadbeef347d" - logsinkID = "50484ec3-19d6-4cd3-b56f-3b0381c289a6" - ) - - body := `{ - "sink_id":"deadbeef-dead-4aa5-beef-deadbeef347d", - "sink_name": "logs-sink", - "sink_type": "opensearch", - "config": { - "url": "https://user:passwd@192.168.0.1:25060", - "index_prefix": "opensearch-logs" - } - }` - - path := fmt.Sprintf("/v2/databases/%s/logsink/%s", dbID, logsinkID) - - mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, http.MethodPut) - fmt.Fprint(w, body) - }) - - _, err := client.Databases.UpdateLogsink(ctx, dbID, logsinkID, &DatabaseUpdateLogsinkRequest{ - Config: &DatabaseLogsinkConfig{ - Server: "192.168.0.1", - Port: 514, - TLS: false, - Format: "rfc3164", - }, - }) - - require.NoError(t, err) -} - -func TestDatabases_ListLogsinks(t *testing.T) { - setup() - defer teardown() - - var ( - dbID = "deadbeef-dead-4aa5-beef-deadbeef347d" - ) - - want := []DatabaseLogsink{ - { - ID: "deadbeef-dead-4aa5-beef-deadbeef347d", - Name: "logs-sink", - Type: "opensearch", - Config: &DatabaseLogsinkConfig{ - URL: "https://user:passwd@192.168.0.1:25060", - IndexPrefix: "opensearch-logs", - }, - }, - { - ID: "d6e95157-5f58-48d0-9023-8cfb409d102a", - Name: "logs-sink-2", - Type: "opensearch", - Config: &DatabaseLogsinkConfig{ - URL: "https://user:passwd@192.168.0.1:25060", - IndexPrefix: "opensearch-logs", - }, - }} - - body := `{ - "sinks": [ - { - "sink_id": "deadbeef-dead-4aa5-beef-deadbeef347d", - "sink_name": "logs-sink", - "sink_type": "opensearch", - "config": { - "url": "https://user:passwd@192.168.0.1:25060", - "index_prefix": "opensearch-logs" - } - }, - { - "sink_id": "d6e95157-5f58-48d0-9023-8cfb409d102a", - "sink_name": "logs-sink-2", - "sink_type": "opensearch", - "config": { - "url": "https://user:passwd@192.168.0.1:25060", - "index_prefix": "opensearch-logs" - } - } - ] - }` - - path := fmt.Sprintf("/v2/databases/%s/logsink", dbID) - - mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, http.MethodGet) - fmt.Fprint(w, body) - }) - - got, _, err := client.Databases.ListLogsinks(ctx, dbID, &ListOptions{}) - require.NoError(t, err) - require.Equal(t, want, got) -} +// func TestDatabases_CreateLogsink(t *testing.T) { +// setup() +// defer teardown() + +// var ( +// dbID = "deadbeef-dead-4aa5-beef-deadbeef347d" +// ) + +// want := &DatabaseLogsink{ +// ID: "deadbeef-dead-4aa5-beef-deadbeef347d", +// Name: "logs-sink", +// Type: "opensearch", +// Config: &DatabaseLogsinkConfig{ +// URL: "https://user:passwd@192.168.0.1:25060", +// IndexPrefix: "opensearch-logs", +// }, +// } + +// body := `{ +// "sink_id":"deadbeef-dead-4aa5-beef-deadbeef347d", +// "sink_name": "logs-sink", +// "sink_type": "opensearch", +// "config": { +// "url": "https://user:passwd@192.168.0.1:25060", +// "index_prefix": "opensearch-logs" +// } +// }` + +// path := fmt.Sprintf("/v2/databases/%s/logsink", dbID) + +// mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) { +// testMethod(t, r, http.MethodPost) +// fmt.Fprint(w, body) +// }) + +// log, _, err := client.Databases.CreateLogsink(ctx, dbID, &DatabaseCreateLogsinkRequest{ +// Name: "logs-sink", +// Type: "opensearch", +// Config: &DatabaseLogsinkConfig{ +// URL: "https://user:passwd@192.168.0.1:25060", +// IndexPrefix: "opensearch-logs", +// }, +// }) + +// require.NoError(t, err) + +// require.Equal(t, want, log) +// } + +// func TestDatabases_GetLogsink(t *testing.T) { +// setup() +// defer teardown() + +// var ( +// dbID = "deadbeef-dead-4aa5-beef-deadbeef347d" +// logsinkID = "50484ec3-19d6-4cd3-b56f-3b0381c289a6" +// ) + +// want := &DatabaseLogsink{ +// ID: "deadbeef-dead-4aa5-beef-deadbeef347d", +// Name: "logs-sink", +// Type: "opensearch", +// Config: &DatabaseLogsinkConfig{ +// URL: "https://user:passwd@192.168.0.1:25060", +// IndexPrefix: "opensearch-logs", +// }, +// } + +// body := `{ +// "sink_id":"deadbeef-dead-4aa5-beef-deadbeef347d", +// "sink_name": "logs-sink", +// "sink_type": "opensearch", +// "config": { +// "url": "https://user:passwd@192.168.0.1:25060", +// "index_prefix": "opensearch-logs" +// } +// }` + +// path := fmt.Sprintf("/v2/databases/%s/logsink/%s", dbID, logsinkID) + +// mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) { +// testMethod(t, r, http.MethodGet) +// fmt.Fprint(w, body) +// }) + +// got, _, err := client.Databases.GetLogsink(ctx, dbID, logsinkID) +// require.NoError(t, err) +// require.Equal(t, want, got) +// } + +// func TestDatabases_UpdateLogsink(t *testing.T) { +// setup() +// defer teardown() + +// var ( +// dbID = "deadbeef-dead-4aa5-beef-deadbeef347d" +// logsinkID = "50484ec3-19d6-4cd3-b56f-3b0381c289a6" +// ) + +// body := `{ +// "sink_id":"deadbeef-dead-4aa5-beef-deadbeef347d", +// "sink_name": "logs-sink", +// "sink_type": "opensearch", +// "config": { +// "url": "https://user:passwd@192.168.0.1:25060", +// "index_prefix": "opensearch-logs" +// } +// }` + +// path := fmt.Sprintf("/v2/databases/%s/logsink/%s", dbID, logsinkID) + +// mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) { +// testMethod(t, r, http.MethodPut) +// fmt.Fprint(w, body) +// }) + +// _, err := client.Databases.UpdateLogsink(ctx, dbID, logsinkID, &DatabaseUpdateLogsinkRequest{ +// Config: &DatabaseLogsinkConfig{ +// Server: "192.168.0.1", +// Port: 514, +// TLS: false, +// Format: "rfc3164", +// }, +// }) + +// require.NoError(t, err) +// } + +// func TestDatabases_ListLogsinks(t *testing.T) { +// setup() +// defer teardown() + +// var ( +// dbID = "deadbeef-dead-4aa5-beef-deadbeef347d" +// ) + +// want := []DatabaseLogsink{ +// { +// ID: "deadbeef-dead-4aa5-beef-deadbeef347d", +// Name: "logs-sink", +// Type: "opensearch", +// Config: &DatabaseLogsinkConfig{ +// URL: "https://user:passwd@192.168.0.1:25060", +// IndexPrefix: "opensearch-logs", +// }, +// }, +// { +// ID: "d6e95157-5f58-48d0-9023-8cfb409d102a", +// Name: "logs-sink-2", +// Type: "opensearch", +// Config: &DatabaseLogsinkConfig{ +// URL: "https://user:passwd@192.168.0.1:25060", +// IndexPrefix: "opensearch-logs", +// }, +// }} + +// body := `{ +// "sinks": [ +// { +// "sink_id": "deadbeef-dead-4aa5-beef-deadbeef347d", +// "sink_name": "logs-sink", +// "sink_type": "opensearch", +// "config": { +// "url": "https://user:passwd@192.168.0.1:25060", +// "index_prefix": "opensearch-logs" +// } +// }, +// { +// "sink_id": "d6e95157-5f58-48d0-9023-8cfb409d102a", +// "sink_name": "logs-sink-2", +// "sink_type": "opensearch", +// "config": { +// "url": "https://user:passwd@192.168.0.1:25060", +// "index_prefix": "opensearch-logs" +// } +// } +// ] +// }` + +// path := fmt.Sprintf("/v2/databases/%s/logsink", dbID) + +// mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) { +// testMethod(t, r, http.MethodGet) +// fmt.Fprint(w, body) +// }) + +// got, _, err := client.Databases.ListLogsinks(ctx, dbID, &ListOptions{}) +// require.NoError(t, err) +// require.Equal(t, want, got) +// } func TestDatabases_DeleteLogsink(t *testing.T) { setup() From 72c4c32eb2e0cf2f78750de4726c1b07077885c8 Mon Sep 17 00:00:00 2001 From: Anna Lushnikova Date: Mon, 7 Oct 2024 12:29:43 -0400 Subject: [PATCH 2/7] Split config logsink --- databases.go | 166 +++++++++++++-------------------------------------- 1 file changed, 43 insertions(+), 123 deletions(-) diff --git a/databases.go b/databases.go index ce1d86c..b63d48b 100644 --- a/databases.go +++ b/databases.go @@ -174,17 +174,21 @@ type DatabasesService interface { ListDatabaseEvents(context.Context, string, *ListOptions) ([]DatabaseEvent, *Response, error) ListIndexes(context.Context, string, *ListOptions) ([]DatabaseIndex, *Response, error) DeleteIndex(context.Context, string, string) (*Response, error) - GetRsyslogLogsink(ctx context.Context, databaseID string, logsinkID string) (*DatabaseRsyslogLogsink, *Response, error) - CreateRsyslogLogsink(ctx context.Context, databaseID string, createLogsink *DatabaseCreateRsyslogLogsinkRequest) (*DatabaseRsyslogLogsink, *Response, error) - UpdateRsyslogLogsink(ctx context.Context, databaseID string, logsinkID string, updateLogsink *DatabaseUpdateRsyslogLogsinkRequest) (*Response, error) - GetElasticsearchLogsink(ctx context.Context, databaseID string, logsinkID string) (*DatabaseElasticsearchLogsink, *Response, error) - CreateElasticsearchLogsink(ctx context.Context, databaseID string, createLogsink *DatabaseCreateElasticsearchLogsinkRequest) (*DatabaseElasticsearchLogsink, *Response, error) - UpdateElasticsearchLogsink(ctx context.Context, databaseID string, logsinkID string, updateLogsink *DatabaseUpdateElasticsearchLogsinkRequest) (*Response, error) - GetOpensearchLogsink(ctx context.Context, databaseID string, logsinkID string) (*DatabaseOpensearchLogsink, *Response, error) - CreateOpensearchLogsink(ctx context.Context, databaseID string, createLogsink *DatabaseCreateOpensearchLogsinkRequest) (*DatabaseOpensearchLogsink, *Response, error) - UpdateOpensearchLogsink(ctx context.Context, databaseID string, logsinkID string, updateLogsink *DatabaseUpdateOpensearchLogsinkRequest) (*Response, error) + // GetRsyslogLogsink(ctx context.Context, databaseID string, logsinkID string) (*DatabaseRsyslogLogsink, *Response, error) + // CreateRsyslogLogsink(ctx context.Context, databaseID string, createLogsink *DatabaseCreateRsyslogLogsinkRequest) (*DatabaseRsyslogLogsink, *Response, error) + // UpdateRsyslogLogsink(ctx context.Context, databaseID string, logsinkID string, updateLogsink *DatabaseUpdateRsyslogLogsinkRequest) (*Response, error) + // GetElasticsearchLogsink(ctx context.Context, databaseID string, logsinkID string) (*DatabaseElasticsearchLogsink, *Response, error) + // CreateElasticsearchLogsink(ctx context.Context, databaseID string, createLogsink *DatabaseCreateElasticsearchLogsinkRequest) (*DatabaseElasticsearchLogsink, *Response, error) + // UpdateElasticsearchLogsink(ctx context.Context, databaseID string, logsinkID string, updateLogsink *DatabaseUpdateElasticsearchLogsinkRequest) (*Response, error) + // GetOpensearchLogsink(ctx context.Context, databaseID string, logsinkID string) (*DatabaseOpensearchLogsink, *Response, error) + // CreateOpensearchLogsink(ctx context.Context, databaseID string, createLogsink *DatabaseCreateOpensearchLogsinkRequest) (*DatabaseOpensearchLogsink, *Response, error) + // UpdateOpensearchLogsink(ctx context.Context, databaseID string, logsinkID string, updateLogsink *DatabaseUpdateOpensearchLogsinkRequest) (*Response, error) ListLogsinks(ctx context.Context, databaseID string, opts *ListOptions) ([]interface{}, *Response, error) DeleteLogsink(ctx context.Context, databaseID, logsinkID string) (*Response, error) + + GetLogsink(ctx context.Context, databaseID string, logsinkID string) (*DatabaseLogsink, *Response, error) + CreateLogsink(ctx context.Context, databaseID string, createLogsink *DatabaseCreateLogsinkRequest) (*DatabaseLogsink, *Response, error) + UpdateLogsink(ctx context.Context, databaseID string, logsinkID string, updateLogsink *DatabaseUpdateLogsinkRequest) (*Response, error) } // DatabasesServiceOp handles communication with the Databases related methods @@ -505,6 +509,26 @@ type DatabaseFirewallRule struct { CreatedAt time.Time `json:"created_at"` } +// DatabaseLogsink represents a logsink. +type DatabaseLogsink struct { + ID string `json:"sink_id"` + Name string `json:"sink_name,required"` + Type string `json:"sink_type,required"` + Config *interface{} `json:"config,required"` +} + +// DatabaseCreateLogsinkRequest is used to create logsink for a database cluster. +type DatabaseCreateLogsinkRequest struct { + Name string `json:"sink_name"` + Type string `json:"sink_type"` + Config *interface{} `json:"config"` +} + +// DatabaseUpdateLogsinkRequest is used to update logsink for a database cluster. +type DatabaseUpdateLogsinkRequest struct { + Config *interface{} `json:"config"` +} + // DatabaseRsyslogLogsink represents a rsyslog logsink. type DatabaseRsyslogLogsink struct { ID string `json:"sink_id"` @@ -888,16 +912,8 @@ type databaseTopicsRoot struct { Topics []DatabaseTopic `json:"topics"` } -type databaseRsyslogLogsinkRoot struct { - Sink DatabaseRsyslogLogsink `json:"sink"` -} - -type databaseElasticsearchLogsinkRoot struct { - Sink DatabaseElasticsearchLogsink `json:"sink"` -} - -type databaseOpensearchLogsinkRoot struct { - Sink DatabaseOpensearchLogsink `json:"sink"` +type databaseLogsinkRoot struct { + Sink DatabaseLogsink `json:"sink"` } type databaseLogsinksRoot struct { @@ -1983,111 +1999,15 @@ func (svc *DatabasesServiceOp) DeleteLogsink(ctx context.Context, databaseID, lo return resp, nil } -// GetRsyslogLogsink gets a logsink for a database. -func (svc *DatabasesServiceOp) GetRsyslogLogsink(ctx context.Context, databaseID string, logsinkID string) (*DatabaseRsyslogLogsink, *Response, error) { - path := fmt.Sprintf(databaseLogsinkPath, databaseID, logsinkID) - req, err := svc.client.NewRequest(ctx, http.MethodGet, path, nil) - if err != nil { - return nil, nil, err - } - - root := new(databaseRsyslogLogsinkRoot) - resp, err := svc.client.Do(ctx, req, root) - if err != nil { - return nil, resp, err - } - return &root.Sink, resp, nil -} - -// CreateRsyslogLogsink creates a new logsink for a database. -func (svc *DatabasesServiceOp) CreateRsyslogLogsink(ctx context.Context, databaseID string, createLogsink *DatabaseCreateRsyslogLogsinkRequest) (*DatabaseRsyslogLogsink, *Response, error) { - path := fmt.Sprintf(databaseLogsinksPath, databaseID) - req, err := svc.client.NewRequest(ctx, http.MethodPost, path, createLogsink) - if err != nil { - return nil, nil, err - } - - root := new(databaseRsyslogLogsinkRoot) - resp, err := svc.client.Do(ctx, req, root) - if err != nil { - return nil, resp, err - } - - return &root.Sink, resp, nil -} - -// UpdateRsyslogLogsink updates a logsink for a database cluster. -func (svc *DatabasesServiceOp) UpdateRsyslogLogsink(ctx context.Context, databaseID string, logsinkID string, updateLogsink *DatabaseUpdateRsyslogLogsinkRequest) (*Response, error) { - path := fmt.Sprintf(databaseLogsinkPath, databaseID, logsinkID) - req, err := svc.client.NewRequest(ctx, http.MethodPut, path, updateLogsink) - if err != nil { - return nil, err - } - - resp, err := svc.client.Do(ctx, req, nil) - if err != nil { - return resp, err - } - return resp, nil -} - -// GetElasticsearchLogsink gets a logsink for a database. -func (svc *DatabasesServiceOp) GetElasticsearchLogsink(ctx context.Context, databaseID string, logsinkID string) (*DatabaseElasticsearchLogsink, *Response, error) { - path := fmt.Sprintf(databaseLogsinkPath, databaseID, logsinkID) - req, err := svc.client.NewRequest(ctx, http.MethodGet, path, nil) - if err != nil { - return nil, nil, err - } - - root := new(databaseElasticsearchLogsinkRoot) - resp, err := svc.client.Do(ctx, req, root) - if err != nil { - return nil, resp, err - } - return &root.Sink, resp, nil -} - -// CreateElasticsearchLogsink creates a new logsink for a database. -func (svc *DatabasesServiceOp) CreateElasticsearchLogsink(ctx context.Context, databaseID string, createLogsink *DatabaseCreateElasticsearchLogsinkRequest) (*DatabaseElasticsearchLogsink, *Response, error) { - path := fmt.Sprintf(databaseLogsinksPath, databaseID) - req, err := svc.client.NewRequest(ctx, http.MethodPost, path, createLogsink) - if err != nil { - return nil, nil, err - } - - root := new(databaseElasticsearchLogsinkRoot) - resp, err := svc.client.Do(ctx, req, root) - if err != nil { - return nil, resp, err - } - - return &root.Sink, resp, nil -} - -// UpdateElasticsearchLogsink updates a logsink for a database cluster. -func (svc *DatabasesServiceOp) UpdateElasticsearchLogsink(ctx context.Context, databaseID string, logsinkID string, updateLogsink *DatabaseUpdateElasticsearchLogsinkRequest) (*Response, error) { - path := fmt.Sprintf(databaseLogsinkPath, databaseID, logsinkID) - req, err := svc.client.NewRequest(ctx, http.MethodPut, path, updateLogsink) - if err != nil { - return nil, err - } - - resp, err := svc.client.Do(ctx, req, nil) - if err != nil { - return resp, err - } - return resp, nil -} - -// GetOpensearchLogsink gets a logsink for a database. -func (svc *DatabasesServiceOp) GetOpensearchLogsink(ctx context.Context, databaseID string, logsinkID string) (*DatabaseOpensearchLogsink, *Response, error) { +// GetLogsink gets a logsink for a database. +func (svc *DatabasesServiceOp) GetLogsink(ctx context.Context, databaseID string, logsinkID string) (*DatabaseLogsink, *Response, error) { path := fmt.Sprintf(databaseLogsinkPath, databaseID, logsinkID) req, err := svc.client.NewRequest(ctx, http.MethodGet, path, nil) if err != nil { return nil, nil, err } - root := new(databaseOpensearchLogsinkRoot) + root := new(databaseLogsinkRoot) resp, err := svc.client.Do(ctx, req, root) if err != nil { return nil, resp, err @@ -2095,15 +2015,15 @@ func (svc *DatabasesServiceOp) GetOpensearchLogsink(ctx context.Context, databas return &root.Sink, resp, nil } -// CreateOpensearchLogsink creates a new logsink for a database. -func (svc *DatabasesServiceOp) CreateOpensearchLogsink(ctx context.Context, databaseID string, createLogsink *DatabaseCreateOpensearchLogsinkRequest) (*DatabaseOpensearchLogsink, *Response, error) { +// CreateLogsink creates a new logsink for a database. +func (svc *DatabasesServiceOp) CreateLogsink(ctx context.Context, databaseID string, createLogsink *DatabaseCreateLogsinkRequest) (*DatabaseLogsink, *Response, error) { path := fmt.Sprintf(databaseLogsinksPath, databaseID) req, err := svc.client.NewRequest(ctx, http.MethodPost, path, createLogsink) if err != nil { return nil, nil, err } - root := new(databaseOpensearchLogsinkRoot) + root := new(databaseLogsinkRoot) resp, err := svc.client.Do(ctx, req, root) if err != nil { return nil, resp, err @@ -2112,8 +2032,8 @@ func (svc *DatabasesServiceOp) CreateOpensearchLogsink(ctx context.Context, data return &root.Sink, resp, nil } -// UpdateOpensearchLogsink updates a logsink for a database cluster. -func (svc *DatabasesServiceOp) UpdateOpensearchLogsink(ctx context.Context, databaseID string, logsinkID string, updateLogsink *DatabaseUpdateOpensearchLogsinkRequest) (*Response, error) { +// UpdateLogsink updates a logsink for a database cluster. +func (svc *DatabasesServiceOp) UpdateLogsink(ctx context.Context, databaseID string, logsinkID string, updateLogsink *DatabaseUpdateLogsinkRequest) (*Response, error) { path := fmt.Sprintf(databaseLogsinkPath, databaseID, logsinkID) req, err := svc.client.NewRequest(ctx, http.MethodPut, path, updateLogsink) if err != nil { From 93435d0f50bf7d061c25f31c250c82b531f1df7b Mon Sep 17 00:00:00 2001 From: Anna Lushnikova Date: Tue, 8 Oct 2024 11:47:35 -0400 Subject: [PATCH 3/7] add tests; remove unused types and functions --- databases.go | 76 +-------- databases_test.go | 421 +++++++++++++++++++++++++--------------------- 2 files changed, 234 insertions(+), 263 deletions(-) diff --git a/databases.go b/databases.go index b63d48b..adc699e 100644 --- a/databases.go +++ b/databases.go @@ -174,21 +174,11 @@ type DatabasesService interface { ListDatabaseEvents(context.Context, string, *ListOptions) ([]DatabaseEvent, *Response, error) ListIndexes(context.Context, string, *ListOptions) ([]DatabaseIndex, *Response, error) DeleteIndex(context.Context, string, string) (*Response, error) - // GetRsyslogLogsink(ctx context.Context, databaseID string, logsinkID string) (*DatabaseRsyslogLogsink, *Response, error) - // CreateRsyslogLogsink(ctx context.Context, databaseID string, createLogsink *DatabaseCreateRsyslogLogsinkRequest) (*DatabaseRsyslogLogsink, *Response, error) - // UpdateRsyslogLogsink(ctx context.Context, databaseID string, logsinkID string, updateLogsink *DatabaseUpdateRsyslogLogsinkRequest) (*Response, error) - // GetElasticsearchLogsink(ctx context.Context, databaseID string, logsinkID string) (*DatabaseElasticsearchLogsink, *Response, error) - // CreateElasticsearchLogsink(ctx context.Context, databaseID string, createLogsink *DatabaseCreateElasticsearchLogsinkRequest) (*DatabaseElasticsearchLogsink, *Response, error) - // UpdateElasticsearchLogsink(ctx context.Context, databaseID string, logsinkID string, updateLogsink *DatabaseUpdateElasticsearchLogsinkRequest) (*Response, error) - // GetOpensearchLogsink(ctx context.Context, databaseID string, logsinkID string) (*DatabaseOpensearchLogsink, *Response, error) - // CreateOpensearchLogsink(ctx context.Context, databaseID string, createLogsink *DatabaseCreateOpensearchLogsinkRequest) (*DatabaseOpensearchLogsink, *Response, error) - // UpdateOpensearchLogsink(ctx context.Context, databaseID string, logsinkID string, updateLogsink *DatabaseUpdateOpensearchLogsinkRequest) (*Response, error) - ListLogsinks(ctx context.Context, databaseID string, opts *ListOptions) ([]interface{}, *Response, error) - DeleteLogsink(ctx context.Context, databaseID, logsinkID string) (*Response, error) - - GetLogsink(ctx context.Context, databaseID string, logsinkID string) (*DatabaseLogsink, *Response, error) CreateLogsink(ctx context.Context, databaseID string, createLogsink *DatabaseCreateLogsinkRequest) (*DatabaseLogsink, *Response, error) + GetLogsink(ctx context.Context, databaseID string, logsinkID string) (*DatabaseLogsink, *Response, error) + ListLogsinks(ctx context.Context, databaseID string, opts *ListOptions) ([]interface{}, *Response, error) UpdateLogsink(ctx context.Context, databaseID string, logsinkID string, updateLogsink *DatabaseUpdateLogsinkRequest) (*Response, error) + DeleteLogsink(ctx context.Context, databaseID, logsinkID string) (*Response, error) } // DatabasesServiceOp handles communication with the Databases related methods @@ -529,26 +519,6 @@ type DatabaseUpdateLogsinkRequest struct { Config *interface{} `json:"config"` } -// DatabaseRsyslogLogsink represents a rsyslog logsink. -type DatabaseRsyslogLogsink struct { - ID string `json:"sink_id"` - Name string `json:"sink_name,required"` - Type string `json:"sink_type,required"` - Config *RsyslogLogsinkConfig `json:"config,required"` -} - -// DatabaseCreateRsyslogLogsinkRequest is used to create rsyslog logsink for a database cluster. -type DatabaseCreateRsyslogLogsinkRequest struct { - Name string `json:"sink_name"` - Type string `json:"sink_type"` - Config *RsyslogLogsinkConfig `json:"config"` -} - -// DatabaseUpdateRsyslogLogsinkRequest is used to update rsyslog logsink for a database cluster. -type DatabaseUpdateRsyslogLogsinkRequest struct { - Config *RsyslogLogsinkConfig `json:"config"` -} - // RsyslogLogsinkConfig represents rsyslog logsink configuration. type RsyslogLogsinkConfig struct { Server string `json:"server,required"` @@ -562,26 +532,6 @@ type RsyslogLogsinkConfig struct { Cert string `json:"cert,omitempty"` } -// DatabaseElasticsearchLogsink represents an elasticsearch logsink. -type DatabaseElasticsearchLogsink struct { - ID string `json:"sink_id"` - Name string `json:"sink_name,required"` - Type string `json:"sink_type,required"` - Config *ElasticsearchLogsinkConfig `json:"config,required"` -} - -// DatabaseCreateElasticsearchLogsinkRequest is used to create elasticsearch logsink for a database cluster. -type DatabaseCreateElasticsearchLogsinkRequest struct { - Name string `json:"sink_name"` - Type string `json:"sink_type"` - Config *ElasticsearchLogsinkConfig `json:"config"` -} - -// DatabaseUpdateElasticsearchLogsinkRequest is used to update elasticsearch logsink for a database cluster. -type DatabaseUpdateElasticsearchLogsinkRequest struct { - Config *ElasticsearchLogsinkConfig `json:"config"` -} - // ElasticsearchLogsinkConfig represents elasticsearch logsink configuration. type ElasticsearchLogsinkConfig struct { URL string `json:"url,required"` @@ -591,26 +541,6 @@ type ElasticsearchLogsinkConfig struct { CA string `json:"ca,omitempty"` } -// DatabaseOpensearchLogsink represents an opensearch logsink. -type DatabaseOpensearchLogsink struct { - ID string `json:"sink_id"` - Name string `json:"sink_name,required"` - Type string `json:"sink_type,required"` - Config *OpensearchLogsinkConfig `json:"config,required"` -} - -// DatabaseCreateOpensearchLogsinkRequest is used to create opensearch logsink for a database cluster. -type DatabaseCreateOpensearchLogsinkRequest struct { - Name string `json:"sink_name"` - Type string `json:"sink_type"` - Config *OpensearchLogsinkConfig `json:"config"` -} - -// DatabaseUpdateOpensearchLogsinkRequest is used to update opensearch logsink for a database cluster. -type DatabaseUpdateOpensearchLogsinkRequest struct { - Config *OpensearchLogsinkConfig `json:"config"` -} - // OpensearchLogsinkConfig represents opensearch logsink configuration. type OpensearchLogsinkConfig struct { URL string `json:"url,required"` diff --git a/databases_test.go b/databases_test.go index 7f65649..2edaf68 100644 --- a/databases_test.go +++ b/databases_test.go @@ -5,6 +5,7 @@ import ( "fmt" "math/big" "net/http" + "reflect" "testing" "time" @@ -3834,196 +3835,236 @@ func TestDatabases_DeleteIndexes(t *testing.T) { require.NoError(t, err) } -// func TestDatabases_CreateLogsink(t *testing.T) { -// setup() -// defer teardown() - -// var ( -// dbID = "deadbeef-dead-4aa5-beef-deadbeef347d" -// ) - -// want := &DatabaseLogsink{ -// ID: "deadbeef-dead-4aa5-beef-deadbeef347d", -// Name: "logs-sink", -// Type: "opensearch", -// Config: &DatabaseLogsinkConfig{ -// URL: "https://user:passwd@192.168.0.1:25060", -// IndexPrefix: "opensearch-logs", -// }, -// } - -// body := `{ -// "sink_id":"deadbeef-dead-4aa5-beef-deadbeef347d", -// "sink_name": "logs-sink", -// "sink_type": "opensearch", -// "config": { -// "url": "https://user:passwd@192.168.0.1:25060", -// "index_prefix": "opensearch-logs" -// } -// }` - -// path := fmt.Sprintf("/v2/databases/%s/logsink", dbID) - -// mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) { -// testMethod(t, r, http.MethodPost) -// fmt.Fprint(w, body) -// }) - -// log, _, err := client.Databases.CreateLogsink(ctx, dbID, &DatabaseCreateLogsinkRequest{ -// Name: "logs-sink", -// Type: "opensearch", -// Config: &DatabaseLogsinkConfig{ -// URL: "https://user:passwd@192.168.0.1:25060", -// IndexPrefix: "opensearch-logs", -// }, -// }) - -// require.NoError(t, err) - -// require.Equal(t, want, log) -// } - -// func TestDatabases_GetLogsink(t *testing.T) { -// setup() -// defer teardown() - -// var ( -// dbID = "deadbeef-dead-4aa5-beef-deadbeef347d" -// logsinkID = "50484ec3-19d6-4cd3-b56f-3b0381c289a6" -// ) - -// want := &DatabaseLogsink{ -// ID: "deadbeef-dead-4aa5-beef-deadbeef347d", -// Name: "logs-sink", -// Type: "opensearch", -// Config: &DatabaseLogsinkConfig{ -// URL: "https://user:passwd@192.168.0.1:25060", -// IndexPrefix: "opensearch-logs", -// }, -// } - -// body := `{ -// "sink_id":"deadbeef-dead-4aa5-beef-deadbeef347d", -// "sink_name": "logs-sink", -// "sink_type": "opensearch", -// "config": { -// "url": "https://user:passwd@192.168.0.1:25060", -// "index_prefix": "opensearch-logs" -// } -// }` - -// path := fmt.Sprintf("/v2/databases/%s/logsink/%s", dbID, logsinkID) - -// mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) { -// testMethod(t, r, http.MethodGet) -// fmt.Fprint(w, body) -// }) - -// got, _, err := client.Databases.GetLogsink(ctx, dbID, logsinkID) -// require.NoError(t, err) -// require.Equal(t, want, got) -// } - -// func TestDatabases_UpdateLogsink(t *testing.T) { -// setup() -// defer teardown() - -// var ( -// dbID = "deadbeef-dead-4aa5-beef-deadbeef347d" -// logsinkID = "50484ec3-19d6-4cd3-b56f-3b0381c289a6" -// ) - -// body := `{ -// "sink_id":"deadbeef-dead-4aa5-beef-deadbeef347d", -// "sink_name": "logs-sink", -// "sink_type": "opensearch", -// "config": { -// "url": "https://user:passwd@192.168.0.1:25060", -// "index_prefix": "opensearch-logs" -// } -// }` - -// path := fmt.Sprintf("/v2/databases/%s/logsink/%s", dbID, logsinkID) - -// mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) { -// testMethod(t, r, http.MethodPut) -// fmt.Fprint(w, body) -// }) - -// _, err := client.Databases.UpdateLogsink(ctx, dbID, logsinkID, &DatabaseUpdateLogsinkRequest{ -// Config: &DatabaseLogsinkConfig{ -// Server: "192.168.0.1", -// Port: 514, -// TLS: false, -// Format: "rfc3164", -// }, -// }) - -// require.NoError(t, err) -// } - -// func TestDatabases_ListLogsinks(t *testing.T) { -// setup() -// defer teardown() - -// var ( -// dbID = "deadbeef-dead-4aa5-beef-deadbeef347d" -// ) - -// want := []DatabaseLogsink{ -// { -// ID: "deadbeef-dead-4aa5-beef-deadbeef347d", -// Name: "logs-sink", -// Type: "opensearch", -// Config: &DatabaseLogsinkConfig{ -// URL: "https://user:passwd@192.168.0.1:25060", -// IndexPrefix: "opensearch-logs", -// }, -// }, -// { -// ID: "d6e95157-5f58-48d0-9023-8cfb409d102a", -// Name: "logs-sink-2", -// Type: "opensearch", -// Config: &DatabaseLogsinkConfig{ -// URL: "https://user:passwd@192.168.0.1:25060", -// IndexPrefix: "opensearch-logs", -// }, -// }} - -// body := `{ -// "sinks": [ -// { -// "sink_id": "deadbeef-dead-4aa5-beef-deadbeef347d", -// "sink_name": "logs-sink", -// "sink_type": "opensearch", -// "config": { -// "url": "https://user:passwd@192.168.0.1:25060", -// "index_prefix": "opensearch-logs" -// } -// }, -// { -// "sink_id": "d6e95157-5f58-48d0-9023-8cfb409d102a", -// "sink_name": "logs-sink-2", -// "sink_type": "opensearch", -// "config": { -// "url": "https://user:passwd@192.168.0.1:25060", -// "index_prefix": "opensearch-logs" -// } -// } -// ] -// }` - -// path := fmt.Sprintf("/v2/databases/%s/logsink", dbID) - -// mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) { -// testMethod(t, r, http.MethodGet) -// fmt.Fprint(w, body) -// }) - -// got, _, err := client.Databases.ListLogsinks(ctx, dbID, &ListOptions{}) -// require.NoError(t, err) -// require.Equal(t, want, got) -// } +func TestDatabases_CreateLogsink(t *testing.T) { + setup() + defer teardown() + + var ( + dbID = "deadbeef-dead-4aa5-beef-deadbeef347d" + ) + var i interface{} + i = OpensearchLogsinkConfig{ + URL: "https://user:passwd@192.168.0.1:25060", + IndexPrefix: "opensearch-logs", + } + + want := &DatabaseLogsink{ + ID: "deadbeef-dead-4aa5-beef-deadbeef347d", + Name: "logs-sink", + Type: "opensearch", + Config: &i, + } + + body := `{ + "sink":{ + "sink_id":"deadbeef-dead-4aa5-beef-deadbeef347d", + "sink_name":"logs-sink", + "sink_type":"opensearch", + "config":{ + "url":"https://user:passwd@192.168.0.1:25060", + "index_prefix":"opensearch-logs" + } + } + }` + + path := fmt.Sprintf("/v2/databases/%s/logsink", dbID) + + mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, http.MethodPost) + fmt.Fprint(w, body) + }) + + logsink, _, err := client.Databases.CreateLogsink(ctx, dbID, &DatabaseCreateLogsinkRequest{ + Name: "logs-sink", + Type: "opensearch", + Config: &i, + }) + + require.NoError(t, err) + + var gotCfg interface{} + + if configMap, ok := (*logsink.Config).(map[string]interface{}); ok { + gotCfg = OpensearchLogsinkConfig{ + URL: configMap["url"].(string), + IndexPrefix: configMap["index_prefix"].(string), + } + } + logsink.Config = &gotCfg + + if !reflect.DeepEqual(*want, *logsink) { + t.Errorf("expected %v, got %v", *want, *logsink) + } +} + +func TestDatabases_GetLogsink(t *testing.T) { + setup() + defer teardown() + + var ( + dbID = "deadbeef-dead-4aa5-beef-deadbeef347d" + logsinkID = "50484ec3-19d6-4cd3-b56f-3b0381c289a6" + ) + var i interface{} + i = OpensearchLogsinkConfig{ + URL: "https://user:passwd@192.168.0.1:25060", + IndexPrefix: "opensearch-logs", + } + + want := &DatabaseLogsink{ + ID: "deadbeef-dead-4aa5-beef-deadbeef347d", + Name: "logs-sink", + Type: "opensearch", + Config: &i, + } + + body := `{ + "sink":{ + "sink_id":"deadbeef-dead-4aa5-beef-deadbeef347d", + "sink_name":"logs-sink", + "sink_type":"opensearch", + "config":{ + "url":"https://user:passwd@192.168.0.1:25060", + "index_prefix":"opensearch-logs" + } + } + }` + + path := fmt.Sprintf("/v2/databases/%s/logsink/%s", dbID, logsinkID) + + mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, http.MethodGet) + fmt.Fprint(w, body) + }) + + got, _, err := client.Databases.GetLogsink(ctx, dbID, logsinkID) + require.NoError(t, err) + + var gotCfg interface{} + + if configMap, ok := (*got.Config).(map[string]interface{}); ok { + gotCfg = OpensearchLogsinkConfig{ + URL: configMap["url"].(string), + IndexPrefix: configMap["index_prefix"].(string), + } + } + got.Config = &gotCfg + + if !reflect.DeepEqual(*want, *got) { + t.Errorf("expected %v, got %v", *want, *got) + } +} + +func TestDatabases_UpdateLogsink(t *testing.T) { + setup() + defer teardown() + + var ( + dbID = "deadbeef-dead-4aa5-beef-deadbeef347d" + logsinkID = "50484ec3-19d6-4cd3-b56f-3b0381c289a6" + ) + + body := `{ + "sink":{ + "sink_id":"deadbeef-dead-4aa5-beef-deadbeef347d", + "sink_name":"logs-sink", + "sink_type":"opensearch", + "config":{ + "url":"https://user:passwd@192.168.0.1:25060", + "index_prefix":"opensearch-logs" + } + } + }` + + path := fmt.Sprintf("/v2/databases/%s/logsink/%s", dbID, logsinkID) + + mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, http.MethodPut) + fmt.Fprint(w, body) + }) + + var i interface{} + i = RsyslogLogsinkConfig{ + Server: "192.168.0.1", + Port: 514, + TLS: false, + Format: "rfc3164", + } + + _, err := client.Databases.UpdateLogsink(ctx, dbID, logsinkID, &DatabaseUpdateLogsinkRequest{ + Config: &i, + }) + + require.NoError(t, err) +} + +func TestDatabases_ListLogsinks(t *testing.T) { + setup() + defer teardown() + + var ( + dbID = "deadbeef-dead-4aa5-beef-deadbeef347d" + ) + + want := []map[string]interface{}{ + { + "config": map[string]interface{}{ + "index_prefix": "opensearch-logs", + "url": "https://user:passwd@192.168.0.1:25060", + }, + "sink_id": "deadbeef-dead-4aa5-beef-deadbeef347d", + "sink_name": "logs-sink", + "sink_type": "opensearch", + }, + { + "config": map[string]interface{}{ + "index_prefix": "opensearch-logs", + "url": "https://user:passwd@192.168.0.1:25060", + }, + "sink_id": "d6e95157-5f58-48d0-9023-8cfb409d102a", + "sink_name": "logs-sink-2", + "sink_type": "opensearch", + }, + } + + body := `{ + "sinks":[ + { + "sink_id":"deadbeef-dead-4aa5-beef-deadbeef347d", + "sink_name":"logs-sink", + "sink_type":"opensearch", + "config":{ + "url":"https://user:passwd@192.168.0.1:25060", + "index_prefix":"opensearch-logs" + } + }, + { + "sink_id":"d6e95157-5f58-48d0-9023-8cfb409d102a", + "sink_name":"logs-sink-2", + "sink_type":"opensearch", + "config":{ + "url":"https://user:passwd@192.168.0.1:25060", + "index_prefix":"opensearch-logs" + } + } + ] + }` + + path := fmt.Sprintf("/v2/databases/%s/logsink", dbID) + + mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, http.MethodGet) + fmt.Fprint(w, body) + }) + + got, _, err := client.Databases.ListLogsinks(ctx, dbID, &ListOptions{}) + require.NoError(t, err) + for i := range got { + if !reflect.DeepEqual(want[i], got[i]) { + t.Errorf("expected %v, got %v", want[i], got[i]) + } + } +} func TestDatabases_DeleteLogsink(t *testing.T) { setup() From efb15764f26af90a4c11c9706125450ee56e3301 Mon Sep 17 00:00:00 2001 From: Anna Lushnikova Date: Tue, 8 Oct 2024 14:52:45 -0400 Subject: [PATCH 4/7] use []DatabaseLogsink in ListLogsinks --- databases.go | 64 +++++++++++++++++++++++------------------------ databases_test.go | 49 +++++++++++++++++++++++------------- 2 files changed, 64 insertions(+), 49 deletions(-) diff --git a/databases.go b/databases.go index adc699e..7cb9e98 100644 --- a/databases.go +++ b/databases.go @@ -176,7 +176,7 @@ type DatabasesService interface { DeleteIndex(context.Context, string, string) (*Response, error) CreateLogsink(ctx context.Context, databaseID string, createLogsink *DatabaseCreateLogsinkRequest) (*DatabaseLogsink, *Response, error) GetLogsink(ctx context.Context, databaseID string, logsinkID string) (*DatabaseLogsink, *Response, error) - ListLogsinks(ctx context.Context, databaseID string, opts *ListOptions) ([]interface{}, *Response, error) + ListLogsinks(ctx context.Context, databaseID string, opts *ListOptions) ([]DatabaseLogsink, *Response, error) UpdateLogsink(ctx context.Context, databaseID string, logsinkID string, updateLogsink *DatabaseUpdateLogsinkRequest) (*Response, error) DeleteLogsink(ctx context.Context, databaseID, logsinkID string) (*Response, error) } @@ -847,7 +847,7 @@ type databaseLogsinkRoot struct { } type databaseLogsinksRoot struct { - Sinks []interface{} `json:"sinks"` + Sinks []DatabaseLogsink `json:"sinks"` } type databaseMetricsCredentialsRoot struct { @@ -1896,40 +1896,24 @@ func (svc *DatabasesServiceOp) DeleteIndex(ctx context.Context, databaseID, name return resp, nil } -// ListTopics returns all topics for a given kafka cluster. -func (svc *DatabasesServiceOp) ListLogsinks(ctx context.Context, databaseID string, opts *ListOptions) ([]interface{}, *Response, error) { +// CreateLogsink creates a new logsink for a database cluster. +func (svc *DatabasesServiceOp) CreateLogsink(ctx context.Context, databaseID string, createLogsink *DatabaseCreateLogsinkRequest) (*DatabaseLogsink, *Response, error) { path := fmt.Sprintf(databaseLogsinksPath, databaseID) - path, err := addOptions(path, opts) - if err != nil { - return nil, nil, err - } - req, err := svc.client.NewRequest(ctx, http.MethodGet, path, nil) + req, err := svc.client.NewRequest(ctx, http.MethodPost, path, createLogsink) if err != nil { return nil, nil, err } - root := new(databaseLogsinksRoot) + + root := new(databaseLogsinkRoot) resp, err := svc.client.Do(ctx, req, root) if err != nil { return nil, resp, err } - return root.Sinks, resp, nil -} -// DeleteLogsink deletes a logsink for a database cluster. -func (svc *DatabasesServiceOp) DeleteLogsink(ctx context.Context, databaseID, logsinkID string) (*Response, error) { - path := fmt.Sprintf(databaseLogsinkPath, databaseID, logsinkID) - req, err := svc.client.NewRequest(ctx, http.MethodDelete, path, nil) - if err != nil { - return nil, err - } - resp, err := svc.client.Do(ctx, req, nil) - if err != nil { - return resp, err - } - return resp, nil + return &root.Sink, resp, nil } -// GetLogsink gets a logsink for a database. +// GetLogsink gets a logsink for a database cluster. func (svc *DatabasesServiceOp) GetLogsink(ctx context.Context, databaseID string, logsinkID string) (*DatabaseLogsink, *Response, error) { path := fmt.Sprintf(databaseLogsinkPath, databaseID, logsinkID) req, err := svc.client.NewRequest(ctx, http.MethodGet, path, nil) @@ -1945,21 +1929,23 @@ func (svc *DatabasesServiceOp) GetLogsink(ctx context.Context, databaseID string return &root.Sink, resp, nil } -// CreateLogsink creates a new logsink for a database. -func (svc *DatabasesServiceOp) CreateLogsink(ctx context.Context, databaseID string, createLogsink *DatabaseCreateLogsinkRequest) (*DatabaseLogsink, *Response, error) { +// ListTopics returns all logsinks for a given database cluster. +func (svc *DatabasesServiceOp) ListLogsinks(ctx context.Context, databaseID string, opts *ListOptions) ([]DatabaseLogsink, *Response, error) { path := fmt.Sprintf(databaseLogsinksPath, databaseID) - req, err := svc.client.NewRequest(ctx, http.MethodPost, path, createLogsink) + path, err := addOptions(path, opts) if err != nil { return nil, nil, err } - - root := new(databaseLogsinkRoot) + req, err := svc.client.NewRequest(ctx, http.MethodGet, path, nil) + if err != nil { + return nil, nil, err + } + root := new(databaseLogsinksRoot) resp, err := svc.client.Do(ctx, req, root) if err != nil { return nil, resp, err } - - return &root.Sink, resp, nil + return root.Sinks, resp, nil } // UpdateLogsink updates a logsink for a database cluster. @@ -1976,3 +1962,17 @@ func (svc *DatabasesServiceOp) UpdateLogsink(ctx context.Context, databaseID str } return resp, nil } + +// DeleteLogsink deletes a logsink for a database cluster. +func (svc *DatabasesServiceOp) DeleteLogsink(ctx context.Context, databaseID, logsinkID string) (*Response, error) { + path := fmt.Sprintf(databaseLogsinkPath, databaseID, logsinkID) + req, err := svc.client.NewRequest(ctx, http.MethodDelete, path, nil) + if err != nil { + return nil, err + } + resp, err := svc.client.Do(ctx, req, nil) + if err != nil { + return resp, err + } + return resp, nil +} diff --git a/databases_test.go b/databases_test.go index 2edaf68..26247bd 100644 --- a/databases_test.go +++ b/databases_test.go @@ -4006,24 +4006,30 @@ func TestDatabases_ListLogsinks(t *testing.T) { dbID = "deadbeef-dead-4aa5-beef-deadbeef347d" ) - want := []map[string]interface{}{ + var cfg1 interface{} + cfg1 = OpensearchLogsinkConfig{ + URL: "https://user:passwd@192.168.0.1:25060", + IndexPrefix: "opensearch-logs", + } + + var cfg2 interface{} + cfg2 = OpensearchLogsinkConfig{ + URL: "https://user:passwd@192.168.0.1:25060", + IndexPrefix: "opensearch-logs", + } + + want := []DatabaseLogsink{ { - "config": map[string]interface{}{ - "index_prefix": "opensearch-logs", - "url": "https://user:passwd@192.168.0.1:25060", - }, - "sink_id": "deadbeef-dead-4aa5-beef-deadbeef347d", - "sink_name": "logs-sink", - "sink_type": "opensearch", + ID: "deadbeef-dead-4aa5-beef-deadbeef347d", + Name: "logs-sink", + Type: "opensearch", + Config: &cfg1, }, { - "config": map[string]interface{}{ - "index_prefix": "opensearch-logs", - "url": "https://user:passwd@192.168.0.1:25060", - }, - "sink_id": "d6e95157-5f58-48d0-9023-8cfb409d102a", - "sink_name": "logs-sink-2", - "sink_type": "opensearch", + ID: "d6e95157-5f58-48d0-9023-8cfb409d102a", + Name: "logs-sink-2", + Type: "opensearch", + Config: &cfg2, }, } @@ -4059,8 +4065,17 @@ func TestDatabases_ListLogsinks(t *testing.T) { got, _, err := client.Databases.ListLogsinks(ctx, dbID, &ListOptions{}) require.NoError(t, err) - for i := range got { - if !reflect.DeepEqual(want[i], got[i]) { + + for i, v := range got { + var gotCfg interface{} + if configMap, ok := (*v.Config).(map[string]interface{}); ok { + gotCfg = OpensearchLogsinkConfig{ + URL: configMap["url"].(string), + IndexPrefix: configMap["index_prefix"].(string), + } + } + v.Config = &gotCfg + if !reflect.DeepEqual(want[i], v) { t.Errorf("expected %v, got %v", want[i], got[i]) } } From 4c9d2f5b67a719f353e1c9bf4632057f00c3288f Mon Sep 17 00:00:00 2001 From: Anna Lushnikova Date: Wed, 9 Oct 2024 11:36:25 -0400 Subject: [PATCH 5/7] adjust get with a real api response schema --- databases.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/databases.go b/databases.go index 7cb9e98..c21b620 100644 --- a/databases.go +++ b/databases.go @@ -1922,7 +1922,7 @@ func (svc *DatabasesServiceOp) GetLogsink(ctx context.Context, databaseID string } root := new(databaseLogsinkRoot) - resp, err := svc.client.Do(ctx, req, root) + resp, err := svc.client.Do(ctx, req, root.Sink) if err != nil { return nil, resp, err } From 0f32c4e3c663a0ad49a44dae1694b9cbceda1007 Mon Sep 17 00:00:00 2001 From: Anna Lushnikova Date: Wed, 9 Oct 2024 12:20:50 -0400 Subject: [PATCH 6/7] use a different schema in root on logsink get --- databases.go | 6 +++--- databases_test.go | 14 ++++++-------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/databases.go b/databases.go index c21b620..ec9fb5b 100644 --- a/databases.go +++ b/databases.go @@ -1921,12 +1921,12 @@ func (svc *DatabasesServiceOp) GetLogsink(ctx context.Context, databaseID string return nil, nil, err } - root := new(databaseLogsinkRoot) - resp, err := svc.client.Do(ctx, req, root.Sink) + root := new(DatabaseLogsink) + resp, err := svc.client.Do(ctx, req, root) if err != nil { return nil, resp, err } - return &root.Sink, resp, nil + return root, resp, nil } // ListTopics returns all logsinks for a given database cluster. diff --git a/databases_test.go b/databases_test.go index 26247bd..7806b11 100644 --- a/databases_test.go +++ b/databases_test.go @@ -3919,14 +3919,12 @@ func TestDatabases_GetLogsink(t *testing.T) { } body := `{ - "sink":{ - "sink_id":"deadbeef-dead-4aa5-beef-deadbeef347d", - "sink_name":"logs-sink", - "sink_type":"opensearch", - "config":{ - "url":"https://user:passwd@192.168.0.1:25060", - "index_prefix":"opensearch-logs" - } + "sink_id":"deadbeef-dead-4aa5-beef-deadbeef347d", + "sink_name":"logs-sink", + "sink_type":"opensearch", + "config":{ + "url":"https://user:passwd@192.168.0.1:25060", + "index_prefix":"opensearch-logs" } }` From 2c2e059f2ea4b6f69c045d4fe70359c3db78ba6b Mon Sep 17 00:00:00 2001 From: Anna Lushnikova Date: Tue, 15 Oct 2024 14:27:33 -0400 Subject: [PATCH 7/7] use DatabaseLogsinkConfig instead of interface{} --- databases.go | 54 +++++++----------- databases_test.go | 140 +++++++++++++++------------------------------- 2 files changed, 65 insertions(+), 129 deletions(-) diff --git a/databases.go b/databases.go index ec9fb5b..bc38c25 100644 --- a/databases.go +++ b/databases.go @@ -501,53 +501,39 @@ type DatabaseFirewallRule struct { // DatabaseLogsink represents a logsink. type DatabaseLogsink struct { - ID string `json:"sink_id"` - Name string `json:"sink_name,required"` - Type string `json:"sink_type,required"` - Config *interface{} `json:"config,required"` + ID string `json:"sink_id"` + Name string `json:"sink_name,required"` + Type string `json:"sink_type,required"` + Config *DatabaseLogsinkConfig `json:"config,required"` } // DatabaseCreateLogsinkRequest is used to create logsink for a database cluster. type DatabaseCreateLogsinkRequest struct { - Name string `json:"sink_name"` - Type string `json:"sink_type"` - Config *interface{} `json:"config"` + Name string `json:"sink_name"` + Type string `json:"sink_type"` + Config *DatabaseLogsinkConfig `json:"config"` } // DatabaseUpdateLogsinkRequest is used to update logsink for a database cluster. type DatabaseUpdateLogsinkRequest struct { - Config *interface{} `json:"config"` -} - -// RsyslogLogsinkConfig represents rsyslog logsink configuration. -type RsyslogLogsinkConfig struct { - Server string `json:"server,required"` - Port int `json:"port,required"` - TLS bool `json:"tls,required"` - Format string `json:"format,required"` - Logline string `json:"logline,omitempty"` - SD string `json:"sd,omitempty"` - CA string `json:"ca,omitempty"` - Key string `json:"key,omitempty"` - Cert string `json:"cert,omitempty"` -} - -// ElasticsearchLogsinkConfig represents elasticsearch logsink configuration. -type ElasticsearchLogsinkConfig struct { - URL string `json:"url,required"` - IndexPrefix string `json:"index_prefix,required"` - IndexDaysMax int `json:"index_days_max,omitempty"` - Timeout float32 `json:"timeout,omitempty"` - CA string `json:"ca,omitempty"` + Config *DatabaseLogsinkConfig `json:"config"` } -// OpensearchLogsinkConfig represents opensearch logsink configuration. -type OpensearchLogsinkConfig struct { - URL string `json:"url,required"` - IndexPrefix string `json:"index_prefix,required"` +// DatabaseLogsinkConfig represents one of the configurable options (rsyslog_logsink, elasticsearch_logsink, or opensearch_logsink) for a logsink. +type DatabaseLogsinkConfig struct { + URL string `json:"url,omitempty"` + IndexPrefix string `json:"index_prefix,omitempty"` IndexDaysMax int `json:"index_days_max,omitempty"` Timeout float32 `json:"timeout,omitempty"` + Server string `json:"server,omitempty"` + Port int `json:"port,omitempty"` + TLS bool `json:"tls,omitempty"` + Format string `json:"format,omitempty"` + Logline string `json:"logline,omitempty"` + SD string `json:"sd,omitempty"` CA string `json:"ca,omitempty"` + Key string `json:"key,omitempty"` + Cert string `json:"cert,omitempty"` } // PostgreSQLConfig holds advanced configurations for PostgreSQL database clusters. diff --git a/databases_test.go b/databases_test.go index 7806b11..c31243b 100644 --- a/databases_test.go +++ b/databases_test.go @@ -5,7 +5,6 @@ import ( "fmt" "math/big" "net/http" - "reflect" "testing" "time" @@ -3842,17 +3841,15 @@ func TestDatabases_CreateLogsink(t *testing.T) { var ( dbID = "deadbeef-dead-4aa5-beef-deadbeef347d" ) - var i interface{} - i = OpensearchLogsinkConfig{ - URL: "https://user:passwd@192.168.0.1:25060", - IndexPrefix: "opensearch-logs", - } want := &DatabaseLogsink{ - ID: "deadbeef-dead-4aa5-beef-deadbeef347d", - Name: "logs-sink", - Type: "opensearch", - Config: &i, + ID: "deadbeef-dead-4aa5-beef-deadbeef347d", + Name: "logs-sink", + Type: "opensearch", + Config: &DatabaseLogsinkConfig{ + URL: "https://user:passwd@192.168.0.1:25060", + IndexPrefix: "opensearch-logs", + }, } body := `{ @@ -3875,26 +3872,16 @@ func TestDatabases_CreateLogsink(t *testing.T) { }) logsink, _, err := client.Databases.CreateLogsink(ctx, dbID, &DatabaseCreateLogsinkRequest{ - Name: "logs-sink", - Type: "opensearch", - Config: &i, + Name: "logs-sink", + Type: "opensearch", + Config: &DatabaseLogsinkConfig{ + URL: "https://user:passwd@192.168.0.1:25060", + IndexPrefix: "opensearch-logs", + }, }) require.NoError(t, err) - - var gotCfg interface{} - - if configMap, ok := (*logsink.Config).(map[string]interface{}); ok { - gotCfg = OpensearchLogsinkConfig{ - URL: configMap["url"].(string), - IndexPrefix: configMap["index_prefix"].(string), - } - } - logsink.Config = &gotCfg - - if !reflect.DeepEqual(*want, *logsink) { - t.Errorf("expected %v, got %v", *want, *logsink) - } + require.Equal(t, want, logsink) } func TestDatabases_GetLogsink(t *testing.T) { @@ -3905,17 +3892,15 @@ func TestDatabases_GetLogsink(t *testing.T) { dbID = "deadbeef-dead-4aa5-beef-deadbeef347d" logsinkID = "50484ec3-19d6-4cd3-b56f-3b0381c289a6" ) - var i interface{} - i = OpensearchLogsinkConfig{ - URL: "https://user:passwd@192.168.0.1:25060", - IndexPrefix: "opensearch-logs", - } want := &DatabaseLogsink{ - ID: "deadbeef-dead-4aa5-beef-deadbeef347d", - Name: "logs-sink", - Type: "opensearch", - Config: &i, + ID: "deadbeef-dead-4aa5-beef-deadbeef347d", + Name: "logs-sink", + Type: "opensearch", + Config: &DatabaseLogsinkConfig{ + URL: "https://user:passwd@192.168.0.1:25060", + IndexPrefix: "opensearch-logs", + }, } body := `{ @@ -3935,22 +3920,9 @@ func TestDatabases_GetLogsink(t *testing.T) { fmt.Fprint(w, body) }) - got, _, err := client.Databases.GetLogsink(ctx, dbID, logsinkID) + logsink, _, err := client.Databases.GetLogsink(ctx, dbID, logsinkID) require.NoError(t, err) - - var gotCfg interface{} - - if configMap, ok := (*got.Config).(map[string]interface{}); ok { - gotCfg = OpensearchLogsinkConfig{ - URL: configMap["url"].(string), - IndexPrefix: configMap["index_prefix"].(string), - } - } - got.Config = &gotCfg - - if !reflect.DeepEqual(*want, *got) { - t.Errorf("expected %v, got %v", *want, *got) - } + require.Equal(t, want, logsink) } func TestDatabases_UpdateLogsink(t *testing.T) { @@ -3981,16 +3953,13 @@ func TestDatabases_UpdateLogsink(t *testing.T) { fmt.Fprint(w, body) }) - var i interface{} - i = RsyslogLogsinkConfig{ - Server: "192.168.0.1", - Port: 514, - TLS: false, - Format: "rfc3164", - } - _, err := client.Databases.UpdateLogsink(ctx, dbID, logsinkID, &DatabaseUpdateLogsinkRequest{ - Config: &i, + Config: &DatabaseLogsinkConfig{ + Server: "192.168.0.1", + Port: 514, + TLS: false, + Format: "rfc3164", + }, }) require.NoError(t, err) @@ -4004,30 +3973,24 @@ func TestDatabases_ListLogsinks(t *testing.T) { dbID = "deadbeef-dead-4aa5-beef-deadbeef347d" ) - var cfg1 interface{} - cfg1 = OpensearchLogsinkConfig{ - URL: "https://user:passwd@192.168.0.1:25060", - IndexPrefix: "opensearch-logs", - } - - var cfg2 interface{} - cfg2 = OpensearchLogsinkConfig{ - URL: "https://user:passwd@192.168.0.1:25060", - IndexPrefix: "opensearch-logs", - } - want := []DatabaseLogsink{ { - ID: "deadbeef-dead-4aa5-beef-deadbeef347d", - Name: "logs-sink", - Type: "opensearch", - Config: &cfg1, + ID: "deadbeef-dead-4aa5-beef-deadbeef347d", + Name: "logs-sink", + Type: "opensearch", + Config: &DatabaseLogsinkConfig{ + URL: "https://user:passwd@192.168.0.1:25060", + IndexPrefix: "opensearch-logs", + }, }, { - ID: "d6e95157-5f58-48d0-9023-8cfb409d102a", - Name: "logs-sink-2", - Type: "opensearch", - Config: &cfg2, + ID: "d6e95157-5f58-48d0-9023-8cfb409d102a", + Name: "logs-sink-2", + Type: "opensearch", + Config: &DatabaseLogsinkConfig{ + URL: "https://user:passwd@192.168.0.1:25060", + IndexPrefix: "opensearch-logs", + }, }, } @@ -4061,22 +4024,9 @@ func TestDatabases_ListLogsinks(t *testing.T) { fmt.Fprint(w, body) }) - got, _, err := client.Databases.ListLogsinks(ctx, dbID, &ListOptions{}) + logsinks, _, err := client.Databases.ListLogsinks(ctx, dbID, &ListOptions{}) require.NoError(t, err) - - for i, v := range got { - var gotCfg interface{} - if configMap, ok := (*v.Config).(map[string]interface{}); ok { - gotCfg = OpensearchLogsinkConfig{ - URL: configMap["url"].(string), - IndexPrefix: configMap["index_prefix"].(string), - } - } - v.Config = &gotCfg - if !reflect.DeepEqual(want[i], v) { - t.Errorf("expected %v, got %v", want[i], got[i]) - } - } + require.Equal(t, want, logsinks) } func TestDatabases_DeleteLogsink(t *testing.T) {