diff --git a/mmv1/products/compute/WireGroup.yaml b/mmv1/products/compute/WireGroup.yaml new file mode 100644 index 000000000000..62416f7773dc --- /dev/null +++ b/mmv1/products/compute/WireGroup.yaml @@ -0,0 +1,193 @@ +# Copyright 2024 Google Inc. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +--- +name: 'WireGroup' +kind: 'compute#wireGroup' +description: | + The WireGroup resource represents a group of redundant wires between interconnects in two different metros. Each WireGroup belongs to a CrossSiteNetwork. A wire group defines endpoints and the wires which exist between them. + +references: + guides: + 'Create a WireGroup': 'https://cloud.google.com/network-connectivity/docs/interconnect/how-to/cross-site/modify-network#add-wire-group' + api: 'https://cloud.google.com/compute/docs/reference/rest/beta/wireGroups' +min_version: beta +docs: +id_format: 'projects/{{project}}/global/crossSiteNetworks/{{cross_site_network}}/wireGroups/{{name}}' +base_url: 'projects/{{project}}/global/crossSiteNetworks/{{cross_site_network}}/wireGroups' +self_link: 'projects/{{project}}/global/crossSiteNetworks/{{cross_site_network}}/wireGroups/{{name}}' +update_verb: 'PATCH' +update_mask: true +import_format: + - 'projects/{{project}}/global/crossSiteNetworks/{{cross_site_network}}/wireGroups/{{name}}' +timeouts: + insert_minutes: 20 + update_minutes: 20 + delete_minutes: 20 +async: + actions: ['create', 'delete', 'update'] + type: 'OpAsync' + operation: + base_url: '{{op_id}}' + result: + resource_inside_response: false +custom_code: + test_check_destroy: 'templates/terraform/custom_check_destroy/wire_group.go.tmpl' +examples: + - name: 'compute_wire_group_basic' + primary_resource_id: 'example-test-wire-group' + vars: + name: 'test-wire-group' + description: 'Example Wire Group' + cross_site_network: 'test-cross-site-network' + min_version: 'beta' + test_env_vars: + project: 'PROJECT_NAME' +parameters: + - name: 'crossSiteNetwork' + type: ResourceRef + description: Required cross site network to which wire group belongs. + required: true + immutable: true + url_param_only: true + resource: 'CrossSiteNetwork' + imports: 'name' + diff_suppress_func: 'tpgresource.CompareResourceNames' + custom_expand: 'templates/terraform/custom_expand/resourceref_with_validation.go.tmpl' + min_version: beta +properties: + - name: 'description' + type: String + description: | + An optional description of this resource. Provide this property when you create the resource. + - name: 'creationTimestamp' + type: Time + description: | + Creation timestamp in RFC3339 text format. + output: true + - name: 'name' + type: String + description: | + Name of the resource. Provided by the client when the resource is created. The name must be + 1-63 characters long, and comply with RFC1035. Specifically, the name must be 1-63 characters + long and match the regular expression `[a-z]([-a-z0-9]*[a-z0-9])?` which means the first + character must be a lowercase letter, and all following characters must be a dash, + lowercase letter, or digit, except the last character, which cannot be a dash. + required: true + validation: + regex: '^[a-z]([-a-z0-9]*[a-z0-9])?$' + - name: endpoints + type: KeyValuePairs + description: | + Endpoints grouped by location, each mapping to interconnect configurations. + properties: + - name: interconnects + type: KeyValuePairs + description: | + Map of interconnect details. + properties: + - name: interconnect + type: string + - name: vlan_tags + type: Array + description: | + VLAN tags for the interconnect. + item_type: + type: integer + - name: adminEnabled + type: boolean + description: | + Indicates whether the wire group is administratively enabled. + - name: wireGroupProperties + type: NestedObject + description: | + Properties specific to the wire group. + properties: + - name: type + type: enum + description: | + Type of wire group (enum). + WIRE: a single pseudowire over two Interconnect connections with no redundancy. + REDUNDANT: two pseudowires over four Interconnect connections, with two connections in one metro and two connections in another metro. + BOX_AND_CROSS: four pseudowires over four Interconnect connections, with two connections in one metro and two connections in another metro. + enum_values: + - 'WIRE' + - 'REDUNDANT' + - 'BOX_AND_CROSS' + - name: wireProperties + type: NestedObject + description: | + Default properties for wires within the group. + properties: + - name: bandwidthUnmetered + type: Integer + description: | + The unmetered bandwidth setting. + - name: faultResponse + type: enum + description: | + Response when a fault is detected in a pseudowire: + NONE: default. + DISABLE_PORT: set the port line protocol down when inline probes detect a fault. This setting is only permitted on port mode pseudowires. + enum_values: + - 'NONE' + - 'DISABLE_PORT' + - name: wires + type: Array + description: | + The single/redundant wire(s) managed by the wire group. + output: true + item_type: + type: NestedObject + properties: + - name: label + type: string + - name: endpoints + type: Array + description: | + 'Wire endpoints are specific Interconnect connections.' + item_type: + type: NestedObject + properties: + - name: interconnect + type: string + - name: vlanTag + type: integer + - name: wireProperties + type: NestedObject + output: true # This is redundant if the parent 'wires' is output: true, but harmless + properties: + - name: bandwidthUnmetered + type: Integer + - name: faultResponse + type: enum + enum_values: + - 'NONE' + - 'DISABLE_PORT' + - name: adminEnabled + type: boolean + - name: topology + type: NestedObject + description: | + Topology details for the wire group configuration. + output: true + properties: + - name: endpoints + type: Array + item_type: + type: NestedObject + properties: + - name: label + type: string + - name: city + type: string diff --git a/mmv1/templates/terraform/custom_check_destroy/cross_site_network.go.tmpl b/mmv1/templates/terraform/custom_check_destroy/cross_site_network.go.tmpl new file mode 100644 index 000000000000..901b6a90bc0d --- /dev/null +++ b/mmv1/templates/terraform/custom_check_destroy/cross_site_network.go.tmpl @@ -0,0 +1,23 @@ + config := acctest.GoogleProviderConfig(t) + + url, err := tpgresource.ReplaceVarsForTest(config, rs, "{{"{{"}}ComputeBasePath{{"}}"}}projects/{{"{{"}}project{{"}}"}}/global/crossSiteNetworks") + if err != nil { + return err + } + + billingProject := "" + + if config.BillingProject != "" { + billingProject = config.BillingProject + } + + _, err = transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "GET", + Project: billingProject, + RawURL: url, + UserAgent: config.UserAgent, + }) + if err == nil { + return fmt.Errorf("ComputeCrossSiteNetwork still exists at %s", url) + } \ No newline at end of file diff --git a/mmv1/templates/terraform/custom_check_destroy/wire_group.go.tmpl b/mmv1/templates/terraform/custom_check_destroy/wire_group.go.tmpl new file mode 100644 index 000000000000..baad2abccd4a --- /dev/null +++ b/mmv1/templates/terraform/custom_check_destroy/wire_group.go.tmpl @@ -0,0 +1,22 @@ + config := acctest.GoogleProviderConfig(t) + url, err := tpgresource.ReplaceVarsForTest(config, rs, "{{"{{"}}ComputeBasePath{{"}}"}}projects/{{"{{"}}project{{"}}"}}/global/crossSiteNetworks/{{"{{"}}cross_site_network{{"}}"}}/wireGroups/{{"{{"}}name{{"}}"}}") + if err != nil { + return err + } + + billingProject := "" + + if config.BillingProject != "" { + billingProject = config.BillingProject + } + + _, err = transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "GET", + Project: billingProject, + RawURL: url, + UserAgent: config.UserAgent, + }) + if err == nil { + return fmt.Errorf("ComputeWireGroup still exists at %s", url) + } \ No newline at end of file diff --git a/mmv1/templates/terraform/custom_delete/cross_site_network.go.tmpl b/mmv1/templates/terraform/custom_delete/cross_site_network.go.tmpl new file mode 100644 index 000000000000..6ae8ec5fdc84 --- /dev/null +++ b/mmv1/templates/terraform/custom_delete/cross_site_network.go.tmpl @@ -0,0 +1,48 @@ + + billingProject := "" + + project, err := tpgresource.GetProject(d, config) + if err != nil { + return fmt.Errorf("Error fetching project for CrossSiteNetwork: %s", err) + } + billingProject = project + + url, err := tpgresource.ReplaceVars(d, config, "{{"{{"}}ComputeBasePath{{"}}"}}projects/{{"{{"}}project{{"}}"}}/global/crossSiteNetworks/{{"{{"}}crossSiteNetworks{{"}}"}}") + if err != nil { + return err + } + + var obj map[string]interface{} + + // err == nil indicates that the billing_project value was found + if bp, err := tpgresource.GetBillingProject(d, config); err == nil { + billingProject = bp + } + + headers := make(http.Header) + + log.Printf("[DEBUG] Deleting CrossSiteNetwork %q", d.Id()) + res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "DELETE", + Project: billingProject, + RawURL: url, + UserAgent: userAgent, + Body: obj, + Timeout: d.Timeout(schema.TimeoutDelete), + Headers: headers, + }) + if err != nil { + return transport_tpg.HandleNotFoundError(err, d, "CrossSiteNetwork") + } + + err = ComputeOperationWaitTime( + config, res, project, "Deleting CrossSiteNetwork", userAgent, + d.Timeout(schema.TimeoutDelete)) + + if err != nil { + return err + } + + log.Printf("[DEBUG] Finished deleting CrossSiteNetwork %q: %#v", d.Id(), res) + return nil \ No newline at end of file diff --git a/mmv1/templates/terraform/examples/compute_wire_group_basic.tf.tmpl b/mmv1/templates/terraform/examples/compute_wire_group_basic.tf.tmpl new file mode 100644 index 000000000000..b4f19b51f3d3 --- /dev/null +++ b/mmv1/templates/terraform/examples/compute_wire_group_basic.tf.tmpl @@ -0,0 +1,25 @@ +data "google_project" "project" { +provider = google-beta +} + +resource "google_compute_cross_site_network" "example-cross-site-network" { + name = "{{index $.Vars "cross_site_network"}}" + description = "Example cross site network" + provider = google-beta +} + +resource "google_compute_wire_group" "{{$.PrimaryResourceId}}" { + name = "{{index $.Vars "name"}}" + description = "{{index $.Vars "description"}}" + cross_site_network = "{{index $.Vars "cross_site_network"}}" + provider = google-beta + depends_on = [ + google_compute_cross_site_network.example-cross-site-network + ] + wire_properties { + bandwidth_unmetered = 10 + } + wire_group_properties { + type = "WIRE" + } +} \ No newline at end of file diff --git a/mmv1/third_party/terraform/services/compute/resource_compute_wire_group_test.go.tmpl b/mmv1/third_party/terraform/services/compute/resource_compute_wire_group_test.go.tmpl new file mode 100644 index 000000000000..7b9fdc3b965f --- /dev/null +++ b/mmv1/third_party/terraform/services/compute/resource_compute_wire_group_test.go.tmpl @@ -0,0 +1,115 @@ +package compute_test +{{ if ne $.TargetVersionName `ga` -}} +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/plancheck" + + "github.com/hashicorp/terraform-provider-google/google/acctest" + "github.com/hashicorp/terraform-provider-google/google/envvar" +) + +func TestAccComputeWireGroup_update(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "project": envvar.GetTestProjectFromEnv(), + "random_suffix": acctest.RandString(t, 10), + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderBetaFactories(t), + CheckDestroy: testAccCheckComputeWireGroupDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccComputeWireGroup_basic(context), + }, + { + ResourceName: "google_compute_wire_group.example-test-wire-group", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"cross_site_network"}, + }, + { + Config: testAccComputeWireGroup_update(context), + ConfigPlanChecks: resource.ConfigPlanChecks{ + PreApply: []plancheck.PlanCheck{ + plancheck.ExpectResourceAction("google_compute_wire_group.example-test-wire-group", plancheck.ResourceActionUpdate), + }, + }, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("google_compute_wire_group.example-test-wire-group", "description", "Example Wire Group Updated"+context["random_suffix"].(string)), + ), + }, + { + ResourceName: "google_compute_wire_group.example-test-wire-group", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"cross_site_network"}, + }, + }, + }) +} + +func testAccComputeWireGroup_basic(context map[string]interface{}) string { + return acctest.Nprintf(` +data "google_project" "project" { +provider = google-beta +} + +resource "google_compute_cross_site_network" "example-cross-site-network" { + name = "tf-test-cross-site-network%{random_suffix}" + description = "Example cross site network" + provider = google-beta +} + +resource "google_compute_wire_group" "example-test-wire-group" { + name = "tf-test-test-wire-group%{random_suffix}" + description = "Example Wire Group%{random_suffix}" + cross_site_network = google_compute_cross_site_network.example-cross-site-network.name + provider = google-beta + depends_on = [ + google_compute_cross_site_network.example-cross-site-network + ] + wire_properties { + bandwidth_unmetered = 1000 + } + wire_group_properties { + type = "REDUNDANT" + } +} +`, context) +} + +func testAccComputeWireGroup_update(context map[string]interface{}) string { + return acctest.Nprintf(` +data "google_project" "project" { +provider = google-beta +} + +resource "google_compute_cross_site_network" "example-cross-site-network" { + name = "tf-test-cross-site-network%{random_suffix}" + description = "Example cross site network" + provider = google-beta +} + +resource "google_compute_wire_group" "example-test-wire-group" { + name = "tf-test-test-wire-group%{random_suffix}" + description = "Example Wire Group Updated%{random_suffix}" + cross_site_network = google_compute_cross_site_network.example-cross-site-network.name + provider = google-beta + depends_on = [ + google_compute_cross_site_network.example-cross-site-network + ] + wire_properties { + bandwidth_unmetered = 1000 + } + wire_group_properties { + type = "REDUNDANT" + } +} +`, context) +} +{{- end }} \ No newline at end of file