diff --git a/.changelog/3723.txt b/.changelog/3723.txt new file mode 100644 index 00000000000..212bfb9895c --- /dev/null +++ b/.changelog/3723.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +`google_endpoints_service` now allows dependent resources to plan based on the `config_id` value. +``` diff --git a/google/resource_endpoints_service.go b/google/resource_endpoints_service.go index 9d309c55e8f..5e0a769a5bd 100644 --- a/google/resource_endpoints_service.go +++ b/google/resource_endpoints_service.go @@ -4,7 +4,11 @@ import ( "encoding/base64" "encoding/json" "errors" + "fmt" "log" + "regexp" + "strconv" + "strings" "time" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" @@ -141,9 +145,34 @@ func resourceEndpointsService() *schema.Resource { }, }, }, + CustomizeDiff: predictServiceId, } } +func predictServiceId(d *schema.ResourceDiff, meta interface{}) error { + if !d.HasChange("openapi_config") && !d.HasChange("grpc_config") && !d.HasChange("protoc_output_base64") { + return nil + } + loc, _ := time.LoadLocation("America/Los_Angeles") + baseDate := time.Now().In(loc).Format("2006-01-02") + oldConfigId := d.Get("config_id").(string) + if match, err := regexp.MatchString(`\d\d\d\d-\d\d-\d\dr\d*`, oldConfigId); !match || err != nil { + // If we do not match the expected format, we will guess + // wrong and that is worse than not guessing. + return nil + } + if strings.HasPrefix(oldConfigId, baseDate) { + n, err := strconv.Atoi(strings.Split(oldConfigId, "r")[1]) + if err != nil { + return err + } + d.SetNew("config_id", fmt.Sprintf("%sr%d", baseDate, n+1)) + } else { + d.SetNew("config_id", baseDate+"r0") + } + return nil +} + func getEndpointServiceOpenAPIConfigSource(configText string) *servicemanagement.ConfigSource { // We need to provide a ConfigSource object to the API whenever submitting a // new config. A ConfigSource contains a ConfigFile which contains the b64 diff --git a/google/resource_endpoints_service_test.go b/google/resource_endpoints_service_test.go index feabb7ddab7..aa7d1241321 100644 --- a/google/resource_endpoints_service_test.go +++ b/google/resource_endpoints_service_test.go @@ -21,7 +21,15 @@ func TestAccEndpointsService_basic(t *testing.T) { Providers: testAccProviders, Steps: []resource.TestStep{ { - Config: testAccEndpointsService_basic(serviceId, getTestProjectFromEnv()), + Config: testAccEndpointsService_basic(serviceId, getTestProjectFromEnv(), "1"), + Check: testAccCheckEndpointExistsByName(t, serviceId), + }, + { + Config: testAccEndpointsService_basic(serviceId, getTestProjectFromEnv(), "2"), + Check: testAccCheckEndpointExistsByName(t, serviceId), + }, + { + Config: testAccEndpointsService_basic(serviceId, getTestProjectFromEnv(), "3"), Check: testAccCheckEndpointExistsByName(t, serviceId), }, }, @@ -97,7 +105,7 @@ func TestEndpointsService_grpcMigrateState(t *testing.T) { } } -func testAccEndpointsService_basic(serviceId, project string) string { +func testAccEndpointsService_basic(serviceId, project, rev string) string { return fmt.Sprintf(` resource "google_endpoints_service" "endpoints_service" { service_name = "%[1]s.endpoints.%[2]s.cloud.goog" @@ -106,7 +114,7 @@ resource "google_endpoints_service" "endpoints_service" { swagger: "2.0" info: description: "A simple Google Cloud Endpoints API example." - title: "Endpoints Example" + title: "Endpoints Example, rev. %[3]s" version: "1.0.0" host: "%[1]s.endpoints.%[2]s.cloud.goog" basePath: "/" @@ -145,7 +153,14 @@ definitions: EOF } -`, serviceId, project) + +resource "random_id" "foo" { + keepers = { + config_id = google_endpoints_service.endpoints_service.config_id + } + byte_length = 8 +} +`, serviceId, project, rev) } func testAccEndpointsService_grpc(serviceId, project string) string {