diff --git a/.go-version b/.go-version index 2d189a90..4fb2b2f8 100644 --- a/.go-version +++ b/.go-version @@ -1 +1 @@ -1.60.3 \ No newline at end of file +1.60.4 \ No newline at end of file diff --git a/docs/index.md b/docs/index.md index 7f61af13..0e232940 100644 --- a/docs/index.md +++ b/docs/index.md @@ -30,4 +30,3 @@ provider "lightstep" { - **api_key** (String) Lightstep organization api key. If not set, the provider will use the environment variable set in `api_key_env_var`. - **api_key_env_var** (String) Environment variable to use when looking up the API Key. -- **environment** (String) The name of the Lightstep environment, must be one of: staging, meta, public. diff --git a/lightstep/resource_stream.go b/lightstep/resource_stream.go index b70c55cd..4f8d8ab7 100644 --- a/lightstep/resource_stream.go +++ b/lightstep/resource_stream.go @@ -56,6 +56,7 @@ func resourceStreamCreate(ctx context.Context, d *schema.ResourceData, m interfa c := m.(*client.Client) if err := resource.RetryContext(ctx, d.Timeout(schema.TimeoutCreate), func() *resource.RetryError { + origQuery := d.Get("query").(string) stream, err := c.CreateStream( ctx, d.Get("project_name").(string), @@ -80,7 +81,8 @@ func resourceStreamCreate(ctx context.Context, d *schema.ResourceData, m interfa return resource.NonRetryableError(fmt.Errorf(err[0].Summary)) } - + // workaround: if read succeeds, persist the *client-side* query expression to avoid backend normalization issue + d.Set("query", origQuery) return nil }); err != nil { return diag.FromErr(fmt.Errorf("Failed to create stream: %v", err)) @@ -173,6 +175,7 @@ func resourceStreamImport(ctx context.Context, d *schema.ResourceData, m interfa if err := setResourceDataFromStream(d, *stream); err != nil { return []*schema.ResourceData{}, fmt.Errorf("Failed to set stream from API response to terraform state: %v", err) } + d.Set("query", stream.Attributes.Query) return []*schema.ResourceData{d}, nil } @@ -223,9 +226,7 @@ func setResourceDataFromStream(d *schema.ResourceData, s client.Stream) error { return fmt.Errorf("Unable to set custom_data resource field: %v", err) } - if err := d.Set("query", s.Attributes.Query); err != nil { - return fmt.Errorf("Unable to set query resource field: %v", err) - } + // don't set query here to avoid backend normalization issue return nil } diff --git a/lightstep/resource_stream_test.go b/lightstep/resource_stream_test.go index 1dd97eed..46a0c899 100644 --- a/lightstep/resource_stream_test.go +++ b/lightstep/resource_stream_test.go @@ -3,11 +3,12 @@ package lightstep import ( "context" "fmt" - "github.com/lightstep/terraform-provider-lightstep/client" "os" "regexp" "testing" + "github.com/lightstep/terraform-provider-lightstep/client" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" ) @@ -116,6 +117,65 @@ resource "lightstep_stream" "import-stream"{ }) } +func TestAccStreamQueryNormalization(t *testing.T) { + var stream client.Stream + + query1 := ` + resource "lightstep_stream" "query_one" { + project_name = ` + fmt.Sprintf("\"%s\"", test_project) + ` + stream_name = "Query 1" + query = "\"error\" IN (\"true\") AND service IN (\"api\")" + } + ` + query1updated := ` + resource "lightstep_stream" "query_one" { + project_name = ` + fmt.Sprintf("\"%s\"", test_project) + ` + stream_name = "Query One" + query = "\"error\" IN (\"true\") AND service IN (\"api\")" + } + ` + query1updatedQuery := ` + resource "lightstep_stream" "query_one" { + project_name = ` + fmt.Sprintf("\"%s\"", test_project) + ` + stream_name = "Query One" + query = "service IN (\"api\") AND \"error\" IN (\"true\")" + } + ` + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccStreamDestroy, + // each step is akin to running a `terraform apply` + Steps: []resource.TestStep{ + { + Config: query1, + Check: resource.ComposeTestCheckFunc( + testAccCheckStreamExists("lightstep_stream.query_one", &stream), + resource.TestCheckResourceAttr("lightstep_stream.query_one", "stream_name", "Query 1"), + resource.TestCheckResourceAttr("lightstep_stream.query_one", "query", "\"error\" IN (\"true\") AND service IN (\"api\")"), + ), + }, + { + Config: query1updated, + Check: resource.ComposeTestCheckFunc( + testAccCheckStreamExists("lightstep_stream.query_one", &stream), + resource.TestCheckResourceAttr("lightstep_stream.query_one", "stream_name", "Query One"), + resource.TestCheckResourceAttr("lightstep_stream.query_one", "query", "\"error\" IN (\"true\") AND service IN (\"api\")"), + ), + }, + { + Config: query1updatedQuery, + Check: resource.ComposeTestCheckFunc( + testAccCheckStreamExists("lightstep_stream.query_one", &stream), + resource.TestCheckResourceAttr("lightstep_stream.query_one", "stream_name", "Query One"), + resource.TestCheckResourceAttr("lightstep_stream.query_one", "query", "service IN (\"api\") AND \"error\" IN (\"true\")"), + ), + }, + }, + }) +} + func testAccCheckStreamExists(resourceName string, stream *client.Stream) resource.TestCheckFunc { return func(s *terraform.State) error { // get stream from TF state