Skip to content

Commit

Permalink
Merge pull request #30 from kvrhdn/refactor_v0.1.0
Browse files Browse the repository at this point in the history
Refactoring for v0.1.0
  • Loading branch information
yvrhdn authored Aug 29, 2020
2 parents aa23fef + b19c37b commit 0b820e2
Show file tree
Hide file tree
Showing 14 changed files with 232 additions and 182 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -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
)
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -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=
Expand Down
211 changes: 76 additions & 135 deletions honeycombio/data_source_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,67 +2,30 @@ 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"
"github.com/kvrhdn/go-honeycombio"
"github.com/kvrhdn/terraform-provider-honeycombio/util"
"github.com/kvrhdn/terraform-provider-honeycombio/honeycombio/internal/hashcode"
)

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,

Schema: map[string]*schema.Schema{
"calculation": {
Type: schema.TypeSet,
Type: schema.TypeList,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"op": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.StringInSlice(validQueryCalculationOps, false),
ValidateFunc: validation.StringInSlice(calculationOpStrings(), false),
},
"column": {
Type: schema.TypeString,
Expand All @@ -83,7 +46,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,
Expand Down Expand Up @@ -135,7 +98,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,
Expand All @@ -144,7 +107,7 @@ func dataSourceHoneycombioQuery() *schema.Resource {
"order": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: validation.StringInSlice([]string{"ascending", "descending"}, false),
ValidateFunc: validation.StringInSlice(sortOrderStrings(), false),
},
},
},
Expand All @@ -163,88 +126,23 @@ func dataSourceHoneycombioQuery() *schema.Resource {
}

func dataSourceHoneycombioQueryRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
calculationSchemas := d.Get("calculation").(*schema.Set).List()
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.CalculateOpCount && 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)
if err != nil {
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)
}

var limit *int
l := d.Get("limit").(int)
if l != 0 {
limit = &l
}

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,
}
}

query := &honeycombio.QuerySpec{
Calculations: calculations,
Filters: filters,
FilterCombination: &filterCombination,
Breakdowns: breakdowns,
Orders: orders,
Limit: limit,
FilterCombination: honeycombio.FilterCombination(d.Get("filter_combination").(string)),
Breakdowns: extractBreakdowns(d),
Orders: extractOrders(d),
Limit: extractLimit(d),
}

jsonQuery, err := encodeQuery(query)
Expand All @@ -253,37 +151,33 @@ 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
}

// encodeQuery in a JSON string.
func encodeQuery(q *honeycombio.QuerySpec) (string, error) {
jsonQueryBytes, err := json.MarshalIndent(q, "", " ")
return string(jsonQueryBytes), err
}
func extractCalculations(d *schema.ResourceData) ([]honeycombio.CalculationSpec, error) {
calculationSchemas := d.Get("calculation").([]interface{})
calculations := make([]honeycombio.CalculationSpec, len(calculationSchemas))

type querySpecValidateDiagFunc func(q *honeycombio.QuerySpec) diag.Diagnostics
for i := range calculationSchemas {
calculation := &calculations[i]

// 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
calculation.Op = honeycombio.CalculationOp(d.Get(fmt.Sprintf("calculation.%d.op", i)).(string))

err := json.Unmarshal([]byte(i.(string)), &q)
if err != nil {
return diag.Errorf("Value of query_json is not a valid query specification")
c, ok := d.GetOk(fmt.Sprintf("calculation.%d.column", i))
if ok {
calculations[i].Column = honeycombio.StringPtr(c.(string))
}

var diagnostics diag.Diagnostics

for _, validator := range validators {
diagnostics = append(diagnostics, validator(&q)...)
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)
}
return diagnostics
}

return calculations, nil
}

func extractFilters(d *schema.ResourceData) ([]honeycombio.FilterSpec, error) {
Expand Down Expand Up @@ -358,3 +252,50 @@ 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 := range orderSchemas {
order := &orders[i]

op, ok := d.GetOk(fmt.Sprintf("order.%d.op", i))
if ok {
order.Op = honeycombio.CalculationOpPtr(honeycombio.CalculationOp(op.(string)))
}

c, ok := d.GetOk(fmt.Sprintf("order.%d.column", i))
if ok {
order.Column = honeycombio.StringPtr(c.(string))
}

so, ok := d.GetOk(fmt.Sprintf("order.%d.order", i))
if ok {
order.Order = honeycombio.SortOrderPtr(honeycombio.SortOrder(so.(string)))
}

// TODO: validation
}

return orders
}

func extractLimit(d *schema.ResourceData) *int {
l, ok := d.GetOk("limit")
if !ok {
return nil
}
return honeycombio.IntPtr(l.(int))
}
18 changes: 16 additions & 2 deletions honeycombio/data_source_query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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\\)"),
Expand Down Expand Up @@ -155,7 +159,7 @@ data "honeycombio_query" "test" {
`
}

func testBadCountQuery() string {
func testQueryCalculationUnneededColumn() string {
return `
data "honeycombio_query" "test" {
calculation {
Expand All @@ -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" {
Expand Down
2 changes: 1 addition & 1 deletion honeycombio/data_source_trigger_recipient.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
4 changes: 2 additions & 2 deletions honeycombio/helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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},
}
Expand Down
Loading

0 comments on commit 0b820e2

Please sign in to comment.