From 0a85a5d27797762723d4ce8cee2f53d7346ed920 Mon Sep 17 00:00:00 2001 From: The Magician Date: Tue, 25 Jul 2023 10:22:44 -0700 Subject: [PATCH] Add traffic status field to cloud run v1 service. (#8410) (#15284) Signed-off-by: Modular Magician --- .changelog/8410.txt | 3 + google/resource_cloud_run_service_test.go | 25 +++++ .../cloudrun/resource_cloud_run_service.go | 97 +++++++++++++++++++ .../docs/r/cloud_run_service.html.markdown | 33 +++++++ 4 files changed, 158 insertions(+) create mode 100644 .changelog/8410.txt diff --git a/.changelog/8410.txt b/.changelog/8410.txt new file mode 100644 index 00000000000..96aafdd021f --- /dev/null +++ b/.changelog/8410.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +cloud-run: added `status.traffic` output fields to `google_cloud_run_service` resource +``` diff --git a/google/resource_cloud_run_service_test.go b/google/resource_cloud_run_service_test.go index 95f8cf9fe52..0244ccf6870 100644 --- a/google/resource_cloud_run_service_test.go +++ b/google/resource_cloud_run_service_test.go @@ -43,6 +43,31 @@ func TestAccCloudRunService_cloudRunServiceUpdate(t *testing.T) { }) } +// test that the status fields are propagated correctly +func TestAccCloudRunService_cloudRunServiceCreateHasStatus(t *testing.T) { + t.Parallel() + + project := envvar.GetTestProjectFromEnv() + name := "tftest-cloudrun-" + acctest.RandString(t, 6) + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + Steps: []resource.TestStep{ + { + Config: testAccCloudRunService_cloudRunServiceUpdate(name, project, "10", "600"), + Check: resource.TestCheckResourceAttrSet("google_cloud_run_service.default", "status.0.traffic.0.revision_name"), + }, + { + ResourceName: "google_cloud_run_service.default", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"metadata.0.resource_version", "status.0.conditions"}, + }, + }, + }) +} + // this test checks that Terraform does not fail with a 409 recreating the same service func TestAccCloudRunService_foregroundDeletion(t *testing.T) { t.Parallel() diff --git a/google/services/cloudrun/resource_cloud_run_service.go b/google/services/cloudrun/resource_cloud_run_service.go index 3634135383d..282bbfac0f9 100644 --- a/google/services/cloudrun/resource_cloud_run_service.go +++ b/google/services/cloudrun/resource_cloud_run_service.go @@ -1031,6 +1031,46 @@ controller. Clients polling for completed reconciliation should poll until observedGeneration = metadata.generation and the Ready condition's status is True or False.`, }, + "traffic": { + Type: schema.TypeList, + Computed: true, + Description: `Traffic specifies how to distribute traffic over a collection of Knative Revisions +and Configurations`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "latest_revision": { + Type: schema.TypeBool, + Computed: true, + Description: `LatestRevision may be optionally provided to indicate that the latest ready +Revision of the Configuration should be used for this traffic target. When +provided LatestRevision must be true if RevisionName is empty; it must be +false when RevisionName is non-empty.`, + }, + "percent": { + Type: schema.TypeInt, + Computed: true, + Description: `Percent specifies percent of the traffic to this Revision or Configuration.`, + }, + "revision_name": { + Type: schema.TypeString, + Computed: true, + Description: `RevisionName of a specific revision to which to send this portion of traffic.`, + }, + "tag": { + Type: schema.TypeString, + Computed: true, + Description: `Tag is optionally used to expose a dedicated url for referencing this target exclusively.`, + }, + "url": { + Type: schema.TypeString, + Computed: true, + Description: `URL displays the URL for accessing tagged traffic targets. URL is displayed in status, +and is disallowed on spec. URL must contain a scheme (e.g. http://) and a hostname, +but may not contain anything else (e.g. basic auth, url path, etc.)`, + }, + }, + }, + }, "url": { Type: schema.TypeString, Computed: true, @@ -2518,6 +2558,8 @@ func flattenCloudRunServiceStatus(v interface{}, d *schema.ResourceData, config flattenCloudRunServiceStatusLatestCreatedRevisionName(original["latestCreatedRevisionName"], d, config) transformed["latest_ready_revision_name"] = flattenCloudRunServiceStatusLatestReadyRevisionName(original["latestReadyRevisionName"], d, config) + transformed["traffic"] = + flattenCloudRunServiceStatusTraffic(original["traffic"], d, config) return []interface{}{transformed} } func flattenCloudRunServiceStatusConditions(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { @@ -2586,6 +2628,61 @@ func flattenCloudRunServiceStatusLatestReadyRevisionName(v interface{}, d *schem return v } +func flattenCloudRunServiceStatusTraffic(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return v + } + l := v.([]interface{}) + transformed := make([]interface{}, 0, len(l)) + for _, raw := range l { + original := raw.(map[string]interface{}) + if len(original) < 1 { + // Do not include empty json objects coming back from the api + continue + } + transformed = append(transformed, map[string]interface{}{ + "revision_name": flattenCloudRunServiceStatusTrafficRevisionName(original["revisionName"], d, config), + "percent": flattenCloudRunServiceStatusTrafficPercent(original["percent"], d, config), + "tag": flattenCloudRunServiceStatusTrafficTag(original["tag"], d, config), + "latest_revision": flattenCloudRunServiceStatusTrafficLatestRevision(original["latestRevision"], d, config), + "url": flattenCloudRunServiceStatusTrafficUrl(original["url"], d, config), + }) + } + return transformed +} +func flattenCloudRunServiceStatusTrafficRevisionName(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenCloudRunServiceStatusTrafficPercent(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + // Handles the string fixed64 format + if strVal, ok := v.(string); ok { + if intVal, err := tpgresource.StringToFixed64(strVal); err == nil { + return intVal + } + } + + // number values are represented as float64 + if floatVal, ok := v.(float64); ok { + intVal := int(floatVal) + return intVal + } + + return v // let terraform core handle it otherwise +} + +func flattenCloudRunServiceStatusTrafficTag(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenCloudRunServiceStatusTrafficLatestRevision(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenCloudRunServiceStatusTrafficUrl(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + func flattenCloudRunServiceMetadata(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { if v == nil { return nil diff --git a/website/docs/r/cloud_run_service.html.markdown b/website/docs/r/cloud_run_service.html.markdown index dd284c097b8..853eacea559 100644 --- a/website/docs/r/cloud_run_service.html.markdown +++ b/website/docs/r/cloud_run_service.html.markdown @@ -1005,6 +1005,12 @@ In addition to the arguments listed above, the following computed attributes are stamped out from this Service's Configuration that has had its "Ready" condition become "True". +* `traffic` - + (Output) + Traffic specifies how to distribute traffic over a collection of Knative Revisions + and Configurations + Structure is [documented below](#nested_traffic). + The `conditions` block contains: @@ -1024,6 +1030,33 @@ In addition to the arguments listed above, the following computed attributes are (Output) Type of domain mapping condition. +The `traffic` block contains: + +* `revision_name` - + (Output) + RevisionName of a specific revision to which to send this portion of traffic. + +* `percent` - + (Output) + Percent specifies percent of the traffic to this Revision or Configuration. + +* `tag` - + (Output) + Tag is optionally used to expose a dedicated url for referencing this target exclusively. + +* `latest_revision` - + (Output) + LatestRevision may be optionally provided to indicate that the latest ready + Revision of the Configuration should be used for this traffic target. When + provided LatestRevision must be true if RevisionName is empty; it must be + false when RevisionName is non-empty. + +* `url` - + (Output) + URL displays the URL for accessing tagged traffic targets. URL is displayed in status, + and is disallowed on spec. URL must contain a scheme (e.g. http://) and a hostname, + but may not contain anything else (e.g. basic auth, url path, etc.) + ## Timeouts This resource provides the following