From 079eb8e8d3fa857d59adfdc097db38132932d922 Mon Sep 17 00:00:00 2001 From: Koenraad Verheyden Date: Mon, 24 Aug 2020 19:30:54 +0200 Subject: [PATCH 1/8] Update go-honeycombio to v0.1.0 --- go.mod | 2 +- go.sum | 4 +- honeycombio/data_source_query.go | 47 ++----------- honeycombio/data_source_trigger_recipient.go | 2 +- honeycombio/helpers_test.go | 4 +- honeycombio/resource_board.go | 20 +++--- honeycombio/resource_board_test.go | 8 +-- honeycombio/resource_marker.go | 2 +- honeycombio/resource_trigger.go | 15 ++--- honeycombio/type_helpers.go | 69 ++++++++++++++++++++ 10 files changed, 100 insertions(+), 73 deletions(-) create mode 100644 honeycombio/type_helpers.go diff --git a/go.mod b/go.mod index 274164dd..5fb655ed 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,6 @@ go 1.14 require ( github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 github.com/hashicorp/terraform-plugin-sdk/v2 v2.0.1 - github.com/kvrhdn/go-honeycombio v0.0.14 + github.com/kvrhdn/go-honeycombio v0.1.0 github.com/stretchr/testify v1.6.1 ) diff --git a/go.sum b/go.sum index 115fea72..a2c1642b 100644 --- a/go.sum +++ b/go.sum @@ -190,8 +190,8 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kvrhdn/go-honeycombio v0.0.14 h1:DjTV1GrIXQZDbEaTgNRmPw32ueUjcsJ5CSirHMaAGXM= -github.com/kvrhdn/go-honeycombio v0.0.14/go.mod h1:UA4oLwic817uNHzdzZotn5j0xSk9paBaPYODFhEDci8= +github.com/kvrhdn/go-honeycombio v0.1.0 h1:6ustPL3+VuBnUZRhtxc0DBjEmg0XByuiR27ijWVEgcA= +github.com/kvrhdn/go-honeycombio v0.1.0/go.mod h1:UA4oLwic817uNHzdzZotn5j0xSk9paBaPYODFhEDci8= github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= diff --git a/honeycombio/data_source_query.go b/honeycombio/data_source_query.go index 2e0a76c0..bdb283ef 100644 --- a/honeycombio/data_source_query.go +++ b/honeycombio/data_source_query.go @@ -14,41 +14,6 @@ import ( "github.com/kvrhdn/terraform-provider-honeycombio/util" ) -var validQueryCalculationOps = []string{ - "COUNT", - "SUM", - "AVG", - "COUNT_DISTINCT", - "MAX", - "MIN", - "P001", - "P01", - "P05", - "P10", - "P25", - "P50", - "P75", - "P90", - "P95", - "P99", - "P999", - "HEATMAP", -} -var validQueryFilterOps = []string{ - "=", - "!=", - ">", - ">=", - "<", - "<=", - "starts-with", - "does-not-start-with", - "exists", - "does-not-exist", - "contains", - "does-not-contain", -} - func dataSourceHoneycombioQuery() *schema.Resource { return &schema.Resource{ ReadContext: dataSourceHoneycombioQueryRead, @@ -62,7 +27,7 @@ func dataSourceHoneycombioQuery() *schema.Resource { "op": { Type: schema.TypeString, Required: true, - ValidateFunc: validation.StringInSlice(validQueryCalculationOps, false), + ValidateFunc: validation.StringInSlice(calculationOpStrings(), false), }, "column": { Type: schema.TypeString, @@ -83,7 +48,7 @@ func dataSourceHoneycombioQuery() *schema.Resource { "op": { Type: schema.TypeString, Required: true, - ValidateFunc: validation.StringInSlice(validQueryFilterOps, false), + ValidateFunc: validation.StringInSlice(filterOpStrings(), false), }, "value": { Type: schema.TypeString, @@ -135,7 +100,7 @@ func dataSourceHoneycombioQuery() *schema.Resource { "op": { Type: schema.TypeString, Optional: true, - ValidateFunc: validation.StringInSlice(validQueryCalculationOps, false), + ValidateFunc: validation.StringInSlice(calculationOpStrings(), false), }, "column": { Type: schema.TypeString, @@ -144,7 +109,7 @@ func dataSourceHoneycombioQuery() *schema.Resource { "order": { Type: schema.TypeString, Optional: true, - ValidateFunc: validation.StringInSlice([]string{"ascending", "descending"}, false), + ValidateFunc: validation.StringInSlice(sortOrderStrings(), false), }, }, }, @@ -177,7 +142,7 @@ func dataSourceHoneycombioQueryRead(ctx context.Context, d *schema.ResourceData, column = &c } - if op == honeycombio.CalculateOpCount && column != nil { + if op == honeycombio.CalculationOpCount && column != nil { return diag.Errorf("calculation op COUNT should not have an accompanying column") } @@ -241,7 +206,7 @@ func dataSourceHoneycombioQueryRead(ctx context.Context, d *schema.ResourceData, query := &honeycombio.QuerySpec{ Calculations: calculations, Filters: filters, - FilterCombination: &filterCombination, + FilterCombination: filterCombination, Breakdowns: breakdowns, Orders: orders, Limit: limit, diff --git a/honeycombio/data_source_trigger_recipient.go b/honeycombio/data_source_trigger_recipient.go index 78cce93f..32cd9ef1 100644 --- a/honeycombio/data_source_trigger_recipient.go +++ b/honeycombio/data_source_trigger_recipient.go @@ -21,7 +21,7 @@ func dataSourceHoneycombioSlackRecipient() *schema.Resource { "type": { Type: schema.TypeString, Required: true, - ValidateFunc: validation.StringInSlice(validTriggerRecipientTypes, false), + ValidateFunc: validation.StringInSlice(triggerRecipientTypeStrings(), false), }, "target": { Type: schema.TypeString, diff --git a/honeycombio/helpers_test.go b/honeycombio/helpers_test.go index 613fadfe..2552237d 100644 --- a/honeycombio/helpers_test.go +++ b/honeycombio/helpers_test.go @@ -15,13 +15,13 @@ func createTriggerWithRecipient(t *testing.T, c *honeycombio.Client, dataset str Query: &honeycombio.QuerySpec{ Calculations: []honeycombio.CalculationSpec{ { - Op: honeycombio.CalculateOpCount, + Op: honeycombio.CalculationOpCount, }, }, }, Threshold: &honeycombio.TriggerThreshold{ Op: honeycombio.TriggerThresholdOpGreaterThan, - Value: &[]float64{100}[0], + Value: honeycombio.Float64Ptr(100), }, Recipients: []honeycombio.TriggerRecipient{recipient}, } diff --git a/honeycombio/resource_board.go b/honeycombio/resource_board.go index 30a20201..966a0e09 100644 --- a/honeycombio/resource_board.go +++ b/honeycombio/resource_board.go @@ -30,7 +30,7 @@ func newBoard() *schema.Resource { Type: schema.TypeString, Optional: true, Default: "list", - ValidateFunc: validation.StringInSlice([]string{"list", "visual"}, false), + ValidateFunc: validation.StringInSlice(boardStyleStrings(), false), }, "query": { Type: schema.TypeList, @@ -86,13 +86,12 @@ func resourceBoardRead(ctx context.Context, d *schema.ResourceData, meta interfa return diag.FromErr(err) } - // API returns nil for filterCombination if set to the default value "AND" + // API returns "" for filterCombination if set to the default value "AND" // To keep the Terraform config simple, we'll explicitly set "AND" ourself for i := range b.Queries { q := &b.Queries[i] - if q.Query.FilterCombination == nil { - filterCombination := honeycombio.FilterCombinationAnd - q.Query.FilterCombination = &filterCombination + if q.Query.FilterCombination == "" { + q.Query.FilterCombination = honeycombio.FilterCombinationAnd } } @@ -154,17 +153,16 @@ func expandBoard(d *schema.ResourceData) (*honeycombio.Board, error) { qs := d.Get("query").([]interface{}) for _, q := range qs { m := q.(map[string]interface{}) - caption := m["caption"].(string) - dataset := m["dataset"].(string) - queryJSON := m["query_json"].(string) + var query honeycombio.QuerySpec - err := json.Unmarshal([]byte(queryJSON), &query) + err := json.Unmarshal([]byte(m["query_json"].(string)), &query) if err != nil { return nil, err } + queries = append(queries, honeycombio.BoardQuery{ - Caption: caption, - Dataset: dataset, + Caption: m["caption"].(string), + Dataset: m["dataset"].(string), Query: query, }) } diff --git a/honeycombio/resource_board_test.go b/honeycombio/resource_board_test.go index b9edc970..61ffbeca 100644 --- a/honeycombio/resource_board_test.go +++ b/honeycombio/resource_board_test.go @@ -88,8 +88,8 @@ func testAccCheckBoardExists(t *testing.T, name string) resource.TestCheckFunc { Query: honeycombio.QuerySpec{ Calculations: []honeycombio.CalculationSpec{ { - Op: honeycombio.CalculateOpAvg, - Column: &[]string{"duration_ms"}[0], + Op: honeycombio.CalculationOpAvg, + Column: honeycombio.StringPtr("duration_ms"), }, }, Filters: []honeycombio.FilterSpec{ @@ -107,8 +107,8 @@ func testAccCheckBoardExists(t *testing.T, name string) resource.TestCheckFunc { Query: honeycombio.QuerySpec{ Calculations: []honeycombio.CalculationSpec{ { - Op: honeycombio.CalculateOpAvg, - Column: &[]string{"duration_ms"}[0], + Op: honeycombio.CalculationOpAvg, + Column: honeycombio.StringPtr("duration_ms"), }, }, Filters: []honeycombio.FilterSpec{ diff --git a/honeycombio/resource_marker.go b/honeycombio/resource_marker.go index 8087e556..0bce9778 100644 --- a/honeycombio/resource_marker.go +++ b/honeycombio/resource_marker.go @@ -45,7 +45,7 @@ func resourceMarkerCreate(ctx context.Context, d *schema.ResourceData, meta inte dataset := d.Get("dataset").(string) - data := honeycombio.MarkerCreateData{ + data := &honeycombio.Marker{ Message: d.Get("message").(string), Type: d.Get("type").(string), URL: d.Get("url").(string), diff --git a/honeycombio/resource_trigger.go b/honeycombio/resource_trigger.go index df57f255..b30e74b5 100644 --- a/honeycombio/resource_trigger.go +++ b/honeycombio/resource_trigger.go @@ -56,7 +56,7 @@ func newTrigger() *schema.Resource { "op": { Type: schema.TypeString, Required: true, - ValidateFunc: validation.StringInSlice([]string{">", ">=", "<", "<="}, false), + ValidateFunc: validation.StringInSlice(triggerThresholdOpStrings(), false), }, "value": { Type: schema.TypeFloat, @@ -89,7 +89,7 @@ func newTrigger() *schema.Resource { Type: schema.TypeString, Optional: true, Computed: true, - ValidateFunc: validation.StringInSlice(validTriggerRecipientTypes, false), + ValidateFunc: validation.StringInSlice(triggerRecipientTypeStrings(), false), }, "target": { Type: schema.TypeString, @@ -103,8 +103,6 @@ func newTrigger() *schema.Resource { } } -var validTriggerRecipientTypes []string = []string{"email", "marker", "pagerduty", "slack"} - func resourceTriggerCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { client := meta.(*honeycombio.Client) @@ -139,9 +137,8 @@ func resourceTriggerRead(ctx context.Context, d *schema.ResourceData, meta inter // API returns nil for filterCombination if set to the default value "AND" // To keep the Terraform config simple, we'll explicitly set "AND" ourself - if t.Query.FilterCombination == nil { - filterCombination := honeycombio.FilterCombinationAnd - t.Query.FilterCombination = &filterCombination + if t.Query.FilterCombination == "" { + t.Query.FilterCombination = honeycombio.FilterCombinationAnd } d.SetId(t.ID) @@ -224,11 +221,9 @@ func expandTrigger(d *schema.ResourceData) (*honeycombio.Trigger, error) { func expandTriggerThreshold(s []interface{}) *honeycombio.TriggerThreshold { d := s[0].(map[string]interface{}) - value := d["value"].(float64) - return &honeycombio.TriggerThreshold{ Op: honeycombio.TriggerThresholdOp(d["op"].(string)), - Value: &value, + Value: honeycombio.Float64Ptr(d["value"].(float64)), } } diff --git a/honeycombio/type_helpers.go b/honeycombio/type_helpers.go new file mode 100644 index 00000000..8ab0b1da --- /dev/null +++ b/honeycombio/type_helpers.go @@ -0,0 +1,69 @@ +package honeycombio + +import "github.com/kvrhdn/go-honeycombio" + +func boardStyleStrings() []string { + in := honeycombio.BoardStyles() + out := make([]string, len(in)) + + for i := range in { + out[i] = string(in[i]) + } + + return out +} + +func calculationOpStrings() []string { + in := honeycombio.CalculationOps() + out := make([]string, len(in)) + + for i := range in { + out[i] = string(in[i]) + } + + return out +} + +func filterOpStrings() []string { + in := honeycombio.FilterOps() + out := make([]string, len(in)) + + for i := range in { + out[i] = string(in[i]) + } + + return out +} + +func sortOrderStrings() []string { + in := honeycombio.SortOrders() + out := make([]string, len(in)) + + for i := range in { + out[i] = string(in[i]) + } + + return out +} + +func triggerRecipientTypeStrings() []string { + in := honeycombio.TriggerRecipientTypes() + out := make([]string, len(in)) + + for i := range in { + out[i] = string(in[i]) + } + + return out +} + +func triggerThresholdOpStrings() []string { + in := honeycombio.TriggerThresholdOps() + out := make([]string, len(in)) + + for i := range in { + out[i] = string(in[i]) + } + + return out +} From 41040e75223f11268470c449a3e6a2bbac6a642a Mon Sep 17 00:00:00 2001 From: Koenraad Verheyden Date: Mon, 24 Aug 2020 20:44:54 +0200 Subject: [PATCH 2/8] Ensure all error messages start with a lowercase letter --- honeycombio/data_source_query.go | 2 +- honeycombio/resource_trigger_test.go | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/honeycombio/data_source_query.go b/honeycombio/data_source_query.go index bdb283ef..ccfc9aae 100644 --- a/honeycombio/data_source_query.go +++ b/honeycombio/data_source_query.go @@ -239,7 +239,7 @@ func validateQueryJSON(validators ...querySpecValidateDiagFunc) schema.SchemaVal err := json.Unmarshal([]byte(i.(string)), &q) if err != nil { - return diag.Errorf("Value of query_json is not a valid query specification") + return diag.Errorf("value of query_json is not a valid query specification") } var diagnostics diag.Diagnostics diff --git a/honeycombio/resource_trigger_test.go b/honeycombio/resource_trigger_test.go index be5b9c7c..1057db9e 100644 --- a/honeycombio/resource_trigger_test.go +++ b/honeycombio/resource_trigger_test.go @@ -67,11 +67,11 @@ func testAccCheckTriggerExists(t *testing.T, name string, trigger *honeycombio.T func testAccCheckTriggerAttributes(t *honeycombio.Trigger) resource.TestCheckFunc { return func(s *terraform.State) error { if t.Name != "Test trigger from terraform-provider-honeycombio" { - return fmt.Errorf("Bad name: %s", t.Name) + return fmt.Errorf("bad name: %s", t.Name) } if t.Frequency != 900 { - return fmt.Errorf("Bad frequency: %d", t.Frequency) + return fmt.Errorf("bad frequency: %d", t.Frequency) } return nil @@ -110,11 +110,11 @@ func TestAccHoneycombioTrigger_validationErrors(t *testing.T) { Steps: []resource.TestStep{ { Config: testAccTriggerConfigWithQuery(dataset, `{]`), - ExpectError: regexp.MustCompile("Value of query_json is not a valid query specification"), + ExpectError: regexp.MustCompile("value of query_json is not a valid query specification"), }, { Config: testAccTriggerConfigWithQuery(dataset, `{"calculations":"bar"}`), - ExpectError: regexp.MustCompile("Value of query_json is not a valid query specification"), + ExpectError: regexp.MustCompile("value of query_json is not a valid query specification"), }, { Config: testAccTriggerConfigWithQuery(dataset, ` From 13eb28f0e8457ed2c35e6683c6bfc143479c035d Mon Sep 17 00:00:00 2001 From: Koenraad Verheyden Date: Mon, 24 Aug 2020 21:02:07 +0200 Subject: [PATCH 3/8] Change type of query.calculations to an (ordered) list --- honeycombio/data_source_query.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/honeycombio/data_source_query.go b/honeycombio/data_source_query.go index ccfc9aae..26990835 100644 --- a/honeycombio/data_source_query.go +++ b/honeycombio/data_source_query.go @@ -20,7 +20,7 @@ func dataSourceHoneycombioQuery() *schema.Resource { Schema: map[string]*schema.Schema{ "calculation": { - Type: schema.TypeSet, + Type: schema.TypeList, Optional: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -128,7 +128,7 @@ func dataSourceHoneycombioQuery() *schema.Resource { } func dataSourceHoneycombioQueryRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - calculationSchemas := d.Get("calculation").(*schema.Set).List() + calculationSchemas := d.Get("calculation").([]interface{}) calculations := make([]honeycombio.CalculationSpec, len(calculationSchemas)) for i, c := range calculationSchemas { From f40572d3a931a8d3278cf487485abe8228825b10 Mon Sep 17 00:00:00 2001 From: Koenraad Verheyden Date: Mon, 24 Aug 2020 21:07:35 +0200 Subject: [PATCH 4/8] Extract shared utilities from data_source_query --- honeycombio/data_source_query.go | 30 ------------------------- honeycombio/query_spec.go | 38 ++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 30 deletions(-) create mode 100644 honeycombio/query_spec.go diff --git a/honeycombio/data_source_query.go b/honeycombio/data_source_query.go index 26990835..f974152a 100644 --- a/honeycombio/data_source_query.go +++ b/honeycombio/data_source_query.go @@ -2,11 +2,9 @@ package honeycombio import ( "context" - "encoding/json" "fmt" "strconv" - "github.com/hashicorp/go-cty/cty" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" @@ -223,34 +221,6 @@ func dataSourceHoneycombioQueryRead(ctx context.Context, d *schema.ResourceData, return nil } -// encodeQuery in a JSON string. -func encodeQuery(q *honeycombio.QuerySpec) (string, error) { - jsonQueryBytes, err := json.MarshalIndent(q, "", " ") - return string(jsonQueryBytes), err -} - -type querySpecValidateDiagFunc func(q *honeycombio.QuerySpec) diag.Diagnostics - -// validateQueryJSON checks that the input can be deserialized as a QuerySpec -// and optionally runs a list of custom validation functions. -func validateQueryJSON(validators ...querySpecValidateDiagFunc) schema.SchemaValidateDiagFunc { - return func(i interface{}, path cty.Path) diag.Diagnostics { - var q honeycombio.QuerySpec - - err := json.Unmarshal([]byte(i.(string)), &q) - if err != nil { - return diag.Errorf("value of query_json is not a valid query specification") - } - - var diagnostics diag.Diagnostics - - for _, validator := range validators { - diagnostics = append(diagnostics, validator(&q)...) - } - return diagnostics - } -} - func extractFilters(d *schema.ResourceData) ([]honeycombio.FilterSpec, error) { filterSchemas := d.Get("filter").([]interface{}) filters := make([]honeycombio.FilterSpec, len(filterSchemas)) diff --git a/honeycombio/query_spec.go b/honeycombio/query_spec.go new file mode 100644 index 00000000..dd773fd3 --- /dev/null +++ b/honeycombio/query_spec.go @@ -0,0 +1,38 @@ +package honeycombio + +import ( + "encoding/json" + + "github.com/hashicorp/go-cty/cty" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/kvrhdn/go-honeycombio" +) + +// encodeQuery in a JSON string. +func encodeQuery(q *honeycombio.QuerySpec) (string, error) { + jsonQueryBytes, err := json.MarshalIndent(q, "", " ") + return string(jsonQueryBytes), err +} + +type querySpecValidateDiagFunc func(q *honeycombio.QuerySpec) diag.Diagnostics + +// validateQueryJSON checks that the input can be deserialized as a QuerySpec +// and optionally runs a list of custom validation functions. +func validateQueryJSON(validators ...querySpecValidateDiagFunc) schema.SchemaValidateDiagFunc { + return func(i interface{}, path cty.Path) diag.Diagnostics { + var q honeycombio.QuerySpec + + err := json.Unmarshal([]byte(i.(string)), &q) + if err != nil { + return diag.Errorf("value of query_json is not a valid query specification") + } + + var diagnostics diag.Diagnostics + + for _, validator := range validators { + diagnostics = append(diagnostics, validator(&q)...) + } + return diagnostics + } +} From 55fd211fc9b7bf35e1150599ff69a7f03f73193f Mon Sep 17 00:00:00 2001 From: Koenraad Verheyden Date: Wed, 26 Aug 2020 02:06:37 +0200 Subject: [PATCH 5/8] Refactor dataSourceHoneycombioQueryRead --- honeycombio/data_source_query.go | 157 +++++++++++++++++-------------- 1 file changed, 88 insertions(+), 69 deletions(-) diff --git a/honeycombio/data_source_query.go b/honeycombio/data_source_query.go index f974152a..f2be66a3 100644 --- a/honeycombio/data_source_query.go +++ b/honeycombio/data_source_query.go @@ -2,6 +2,7 @@ package honeycombio import ( "context" + "errors" "fmt" "strconv" @@ -126,28 +127,9 @@ func dataSourceHoneycombioQuery() *schema.Resource { } func dataSourceHoneycombioQueryRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - calculationSchemas := d.Get("calculation").([]interface{}) - calculations := make([]honeycombio.CalculationSpec, len(calculationSchemas)) - - for i, c := range calculationSchemas { - cMap := c.(map[string]interface{}) - - op := honeycombio.CalculationOp(cMap["op"].(string)) - - var column *string - c := cMap["column"].(string) - if c != "" { - column = &c - } - - if op == honeycombio.CalculationOpCount && column != nil { - return diag.Errorf("calculation op COUNT should not have an accompanying column") - } - - calculations[i] = honeycombio.CalculationSpec{ - Op: op, - Column: column, - } + calculations, err := extractCalculations(d) + if err != nil { + return diag.FromErr(err) } filters, err := extractFilters(d) @@ -155,70 +137,52 @@ func dataSourceHoneycombioQueryRead(ctx context.Context, d *schema.ResourceData, return diag.FromErr(err) } - filterCombination := honeycombio.FilterCombination(d.Get("filter_combination").(string)) - - breakdownsRaw := d.Get("breakdowns").([]interface{}) - breakdowns := make([]string, len(breakdownsRaw)) - - for i, b := range breakdownsRaw { - breakdowns[i] = b.(string) + query := &honeycombio.QuerySpec{ + Calculations: calculations, + Filters: filters, + FilterCombination: honeycombio.FilterCombination(d.Get("filter_combination").(string)), + Breakdowns: extractBreakdowns(d), + Orders: extractOrders(d), + Limit: extractLimit(d), } - var limit *int - l := d.Get("limit").(int) - if l != 0 { - limit = &l + jsonQuery, err := encodeQuery(query) + if err != nil { + return diag.FromErr(err) } - orderSchemas := d.Get("order").([]interface{}) - orders := make([]honeycombio.OrderSpec, len(orderSchemas)) + d.Set("json", jsonQuery) + d.SetId(strconv.Itoa(util.HashString(jsonQuery))) - for i, o := range orderSchemas { - oMap := o.(map[string]interface{}) + return nil +} - var op *honeycombio.CalculationOp - opValue := honeycombio.CalculationOp(oMap["op"].(string)) - if opValue != "" { - op = &opValue - } +func extractCalculations(d *schema.ResourceData) ([]honeycombio.CalculationSpec, error) { + calculationSchemas := d.Get("calculation").([]interface{}) + calculations := make([]honeycombio.CalculationSpec, len(calculationSchemas)) + + for i, c := range calculationSchemas { + cMap := c.(map[string]interface{}) + + op := honeycombio.CalculationOp(cMap["op"].(string)) var column *string - columnValue := oMap["column"].(string) - if columnValue != "" { - column = &columnValue + c := cMap["column"].(string) + if c != "" { + column = &c } - var sortOrder *honeycombio.SortOrder - sortOrderValue := honeycombio.SortOrder(oMap["order"].(string)) - if sortOrderValue != "" { - sortOrder = &sortOrderValue + if op == honeycombio.CalculationOpCount && column != nil { + return nil, errors.New("calculation op COUNT should not have an accompanying column") } - orders[i] = honeycombio.OrderSpec{ + calculations[i] = honeycombio.CalculationSpec{ Op: op, Column: column, - Order: sortOrder, } } - query := &honeycombio.QuerySpec{ - Calculations: calculations, - Filters: filters, - FilterCombination: filterCombination, - Breakdowns: breakdowns, - Orders: orders, - Limit: limit, - } - - jsonQuery, err := encodeQuery(query) - if err != nil { - return diag.FromErr(err) - } - - d.Set("json", jsonQuery) - d.SetId(strconv.Itoa(util.HashString(jsonQuery))) - - return nil + return calculations, nil } func extractFilters(d *schema.ResourceData) ([]honeycombio.FilterSpec, error) { @@ -293,3 +257,58 @@ func extractFilter(d *schema.ResourceData, index int) (honeycombio.FilterSpec, e } return filter, nil } + +func extractBreakdowns(d *schema.ResourceData) []string { + breakdownsRaw := d.Get("breakdowns").([]interface{}) + breakdowns := make([]string, len(breakdownsRaw)) + + for i, b := range breakdownsRaw { + breakdowns[i] = b.(string) + } + + return breakdowns +} + +func extractOrders(d *schema.ResourceData) []honeycombio.OrderSpec { + orderSchemas := d.Get("order").([]interface{}) + orders := make([]honeycombio.OrderSpec, len(orderSchemas)) + + for i, o := range orderSchemas { + oMap := o.(map[string]interface{}) + + var op *honeycombio.CalculationOp + opValue := honeycombio.CalculationOp(oMap["op"].(string)) + if opValue != "" { + op = &opValue + } + + var column *string + columnValue := oMap["column"].(string) + if columnValue != "" { + column = &columnValue + } + + var sortOrder *honeycombio.SortOrder + sortOrderValue := honeycombio.SortOrder(oMap["order"].(string)) + if sortOrderValue != "" { + sortOrder = &sortOrderValue + } + + orders[i] = honeycombio.OrderSpec{ + Op: op, + Column: column, + Order: sortOrder, + } + } + + return orders +} + +func extractLimit(d *schema.ResourceData) *int { + l, ok := d.GetOk("limit") + if !ok { + return nil + } + li := l.(int) + return &li +} From 3cc0c4ec26cc99573d07ab4fa891d0bc51fe5404 Mon Sep 17 00:00:00 2001 From: Koenraad Verheyden Date: Wed, 26 Aug 2020 02:07:08 +0200 Subject: [PATCH 6/8] Replace resourceMarkerDelete by schema.NoopContext --- honeycombio/resource_marker.go | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/honeycombio/resource_marker.go b/honeycombio/resource_marker.go index 0bce9778..52892746 100644 --- a/honeycombio/resource_marker.go +++ b/honeycombio/resource_marker.go @@ -13,7 +13,7 @@ func newMarker() *schema.Resource { CreateContext: resourceMarkerCreate, ReadContext: resourceMarkerRead, UpdateContext: nil, - DeleteContext: resourceMarkerDelete, + DeleteContext: schema.NoopContext, Schema: map[string]*schema.Schema{ "message": { @@ -77,8 +77,3 @@ func resourceMarkerRead(ctx context.Context, d *schema.ResourceData, meta interf d.Set("url", marker.URL) return nil } - -func resourceMarkerDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - // do nothing on destroy - return nil -} From 4900fdb240f26c62f12756b627b4e3c5585febed Mon Sep 17 00:00:00 2001 From: Koenraad Verheyden Date: Wed, 26 Aug 2020 02:28:36 +0200 Subject: [PATCH 7/8] Simplify data source query implementation --- honeycombio/data_source_query.go | 59 +++++++++++---------------- honeycombio/data_source_query_test.go | 18 +++++++- 2 files changed, 39 insertions(+), 38 deletions(-) diff --git a/honeycombio/data_source_query.go b/honeycombio/data_source_query.go index f2be66a3..d1c9d8f7 100644 --- a/honeycombio/data_source_query.go +++ b/honeycombio/data_source_query.go @@ -2,7 +2,6 @@ package honeycombio import ( "context" - "errors" "fmt" "strconv" @@ -161,24 +160,20 @@ func extractCalculations(d *schema.ResourceData) ([]honeycombio.CalculationSpec, calculationSchemas := d.Get("calculation").([]interface{}) calculations := make([]honeycombio.CalculationSpec, len(calculationSchemas)) - for i, c := range calculationSchemas { - cMap := c.(map[string]interface{}) + for i := range calculationSchemas { + calculation := &calculations[i] - op := honeycombio.CalculationOp(cMap["op"].(string)) + calculation.Op = honeycombio.CalculationOp(d.Get(fmt.Sprintf("calculation.%d.op", i)).(string)) - var column *string - c := cMap["column"].(string) - if c != "" { - column = &c + c, ok := d.GetOk(fmt.Sprintf("calculation.%d.column", i)) + if ok { + calculations[i].Column = honeycombio.StringPtr(c.(string)) } - if op == honeycombio.CalculationOpCount && column != nil { - return nil, errors.New("calculation op COUNT should not have an accompanying column") - } - - calculations[i] = honeycombio.CalculationSpec{ - Op: op, - Column: column, + if calculation.Op == honeycombio.CalculationOpCount && calculation.Column != nil { + return nil, fmt.Errorf("calculation op %s should not have an accompanying column", calculation.Op) + } else if calculation.Op != honeycombio.CalculationOpCount && calculation.Column == nil { + return nil, fmt.Errorf("calculation op %s is missing an accompanying column", calculation.Op) } } @@ -273,32 +268,25 @@ func extractOrders(d *schema.ResourceData) []honeycombio.OrderSpec { orderSchemas := d.Get("order").([]interface{}) orders := make([]honeycombio.OrderSpec, len(orderSchemas)) - for i, o := range orderSchemas { - oMap := o.(map[string]interface{}) + for i := range orderSchemas { + order := &orders[i] - var op *honeycombio.CalculationOp - opValue := honeycombio.CalculationOp(oMap["op"].(string)) - if opValue != "" { - op = &opValue + op, ok := d.GetOk(fmt.Sprintf("order.%d.op", i)) + if ok { + order.Op = honeycombio.CalculationOpPtr(honeycombio.CalculationOp(op.(string))) } - var column *string - columnValue := oMap["column"].(string) - if columnValue != "" { - column = &columnValue + c, ok := d.GetOk(fmt.Sprintf("order.%d.column", i)) + if ok { + order.Column = honeycombio.StringPtr(c.(string)) } - var sortOrder *honeycombio.SortOrder - sortOrderValue := honeycombio.SortOrder(oMap["order"].(string)) - if sortOrderValue != "" { - sortOrder = &sortOrderValue + so, ok := d.GetOk(fmt.Sprintf("order.%d.order", i)) + if ok { + order.Order = honeycombio.SortOrderPtr(honeycombio.SortOrder(so.(string))) } - orders[i] = honeycombio.OrderSpec{ - Op: op, - Column: column, - Order: sortOrder, - } + // TODO: validation } return orders @@ -309,6 +297,5 @@ func extractLimit(d *schema.ResourceData) *int { if !ok { return nil } - li := l.(int) - return &li + return honeycombio.IntPtr(l.(int)) } diff --git a/honeycombio/data_source_query_test.go b/honeycombio/data_source_query_test.go index 62260d07..c21ecea7 100644 --- a/honeycombio/data_source_query_test.go +++ b/honeycombio/data_source_query_test.go @@ -116,9 +116,13 @@ func TestAccDataSourceHoneycombioQuery_validationChecks(t *testing.T) { ExpectError: regexp.MustCompile("filter operation exists must not"), }, { - Config: testBadCountQuery(), + Config: testQueryCalculationUnneededColumn(), ExpectError: regexp.MustCompile("calculation op COUNT should not have an accompanying column"), }, + { + Config: testQueryCalculationMissingColumn(), + ExpectError: regexp.MustCompile("calculation op AVG is missing an accompanying column"), + }, { Config: testQueryWithLimit(0), ExpectError: regexp.MustCompile("expected limit to be in the range \\(1 - 1000\\)"), @@ -155,7 +159,7 @@ data "honeycombio_query" "test" { ` } -func testBadCountQuery() string { +func testQueryCalculationUnneededColumn() string { return ` data "honeycombio_query" "test" { calculation { @@ -166,6 +170,16 @@ data "honeycombio_query" "test" { ` } +func testQueryCalculationMissingColumn() string { + return ` +data "honeycombio_query" "test" { + calculation { + op = "AVG" + } +} +` +} + func testConflictingValues() string { return ` data "honeycombio_query" "test" { From b19c37b01c4a3d411295dbf3abc69f9f87680c54 Mon Sep 17 00:00:00 2001 From: Koenraad Verheyden Date: Wed, 26 Aug 2020 22:45:57 +0200 Subject: [PATCH 8/8] Move util.HashString to internal/hashcode.String --- honeycombio/data_source_query.go | 4 ++-- util/util.go => honeycombio/internal/hashcode/hashcode.go | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) rename util/util.go => honeycombio/internal/hashcode/hashcode.go (83%) diff --git a/honeycombio/data_source_query.go b/honeycombio/data_source_query.go index d1c9d8f7..e6ceb996 100644 --- a/honeycombio/data_source_query.go +++ b/honeycombio/data_source_query.go @@ -9,7 +9,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/kvrhdn/go-honeycombio" - "github.com/kvrhdn/terraform-provider-honeycombio/util" + "github.com/kvrhdn/terraform-provider-honeycombio/honeycombio/internal/hashcode" ) func dataSourceHoneycombioQuery() *schema.Resource { @@ -151,7 +151,7 @@ func dataSourceHoneycombioQueryRead(ctx context.Context, d *schema.ResourceData, } d.Set("json", jsonQuery) - d.SetId(strconv.Itoa(util.HashString(jsonQuery))) + d.SetId(strconv.Itoa(hashcode.String(jsonQuery))) return nil } diff --git a/util/util.go b/honeycombio/internal/hashcode/hashcode.go similarity index 83% rename from util/util.go rename to honeycombio/internal/hashcode/hashcode.go index e7467588..b3f795ee 100644 --- a/util/util.go +++ b/honeycombio/internal/hashcode/hashcode.go @@ -1,15 +1,15 @@ -package util +package hashcode import "hash/crc32" -// HashString hashes a string to a unique hashcode. +// String hashes a string to a unique hashcode. // // crc32 returns a uint32, but for our use we need and non negative integer. // Here we cast to an integer and invert it if the result is negative. // // This function was originally provided by Terraform's helper/hashcode. // https://www.terraform.io/docs/extend/guides/v2-upgrade-guide.html#removal-of-helper-hashcode-package -func HashString(s string) int { +func String(s string) int { v := int(crc32.ChecksumIEEE([]byte(s))) if v >= 0 { return v