From fdeac73ab6ea0f7bbe9f45369131073d43714f1f Mon Sep 17 00:00:00 2001 From: The Magician Date: Fri, 1 Feb 2019 16:17:53 -0800 Subject: [PATCH] Add fields to InterconnectAttachment to allow for PARTNER interconnects (#2959) Signed-off-by: Modular Magician --- ...esource_compute_interconnect_attachment.go | 92 +++++++++++++++++-- ...pute_interconnect_attachment.html.markdown | 38 +++++++- 2 files changed, 119 insertions(+), 11 deletions(-) diff --git a/google/resource_compute_interconnect_attachment.go b/google/resource_compute_interconnect_attachment.go index e9373b1f..81967854 100644 --- a/google/resource_compute_interconnect_attachment.go +++ b/google/resource_compute_interconnect_attachment.go @@ -22,6 +22,7 @@ import ( "time" "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" "google.golang.org/api/compute/v1" ) @@ -41,12 +42,6 @@ func resourceComputeInterconnectAttachment() *schema.Resource { }, Schema: map[string]*schema.Schema{ - "interconnect": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - DiffSuppressFunc: compareSelfLinkOrResourceName, - }, "name": { Type: schema.TypeString, Required: true, @@ -72,6 +67,17 @@ func resourceComputeInterconnectAttachment() *schema.Resource { Optional: true, ForceNew: true, }, + "edge_availability_domain": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + "interconnect": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + DiffSuppressFunc: compareSelfLinkOrResourceName, + }, "region": { Type: schema.TypeString, Computed: true, @@ -79,6 +85,13 @@ func resourceComputeInterconnectAttachment() *schema.Resource { ForceNew: true, DiffSuppressFunc: compareSelfLinkOrResourceName, }, + "type": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + ValidateFunc: validation.StringInSlice([]string{"DEDICATED", "PARTNER", "PARTNER_PROVIDER", ""}, false), + }, "vlan_tag8021q": { Type: schema.TypeInt, Optional: true, @@ -100,6 +113,14 @@ func resourceComputeInterconnectAttachment() *schema.Resource { Type: schema.TypeString, Computed: true, }, + "pairing_key": { + Type: schema.TypeString, + Computed: true, + }, + "partner_asn": { + Type: schema.TypeString, + Computed: true, + }, "private_interconnect_info": { Type: schema.TypeList, Computed: true, @@ -113,6 +134,10 @@ func resourceComputeInterconnectAttachment() *schema.Resource { }, }, }, + "state": { + Type: schema.TypeString, + Computed: true, + }, "project": { Type: schema.TypeString, Optional: true, @@ -143,6 +168,18 @@ func resourceComputeInterconnectAttachmentCreate(d *schema.ResourceData, meta in } else if v, ok := d.GetOkExists("description"); !isEmptyValue(reflect.ValueOf(descriptionProp)) && (ok || !reflect.DeepEqual(v, descriptionProp)) { obj["description"] = descriptionProp } + edgeAvailabilityDomainProp, err := expandComputeInterconnectAttachmentEdgeAvailabilityDomain(d.Get("edge_availability_domain"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("edge_availability_domain"); !isEmptyValue(reflect.ValueOf(edgeAvailabilityDomainProp)) && (ok || !reflect.DeepEqual(v, edgeAvailabilityDomainProp)) { + obj["edgeAvailabilityDomain"] = edgeAvailabilityDomainProp + } + typeProp, err := expandComputeInterconnectAttachmentType(d.Get("type"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("type"); !isEmptyValue(reflect.ValueOf(typeProp)) && (ok || !reflect.DeepEqual(v, typeProp)) { + obj["type"] = typeProp + } routerProp, err := expandComputeInterconnectAttachmentRouter(d.Get("router"), d, config) if err != nil { return err @@ -250,9 +287,24 @@ func resourceComputeInterconnectAttachmentRead(d *schema.ResourceData, meta inte if err := d.Set("description", flattenComputeInterconnectAttachmentDescription(res["description"], d)); err != nil { return fmt.Errorf("Error reading InterconnectAttachment: %s", err) } + if err := d.Set("edge_availability_domain", flattenComputeInterconnectAttachmentEdgeAvailabilityDomain(res["edgeAvailabilityDomain"], d)); err != nil { + return fmt.Errorf("Error reading InterconnectAttachment: %s", err) + } + if err := d.Set("pairing_key", flattenComputeInterconnectAttachmentPairingKey(res["pairingKey"], d)); err != nil { + return fmt.Errorf("Error reading InterconnectAttachment: %s", err) + } + if err := d.Set("partner_asn", flattenComputeInterconnectAttachmentPartnerAsn(res["partnerAsn"], d)); err != nil { + return fmt.Errorf("Error reading InterconnectAttachment: %s", err) + } if err := d.Set("private_interconnect_info", flattenComputeInterconnectAttachmentPrivateInterconnectInfo(res["privateInterconnectInfo"], d)); err != nil { return fmt.Errorf("Error reading InterconnectAttachment: %s", err) } + if err := d.Set("type", flattenComputeInterconnectAttachmentType(res["type"], d)); err != nil { + return fmt.Errorf("Error reading InterconnectAttachment: %s", err) + } + if err := d.Set("state", flattenComputeInterconnectAttachmentState(res["state"], d)); err != nil { + return fmt.Errorf("Error reading InterconnectAttachment: %s", err) + } if err := d.Set("google_reference_id", flattenComputeInterconnectAttachmentGoogleReferenceId(res["googleReferenceId"], d)); err != nil { return fmt.Errorf("Error reading InterconnectAttachment: %s", err) } @@ -350,6 +402,18 @@ func flattenComputeInterconnectAttachmentDescription(v interface{}, d *schema.Re return v } +func flattenComputeInterconnectAttachmentEdgeAvailabilityDomain(v interface{}, d *schema.ResourceData) interface{} { + return v +} + +func flattenComputeInterconnectAttachmentPairingKey(v interface{}, d *schema.ResourceData) interface{} { + return v +} + +func flattenComputeInterconnectAttachmentPartnerAsn(v interface{}, d *schema.ResourceData) interface{} { + return v +} + func flattenComputeInterconnectAttachmentPrivateInterconnectInfo(v interface{}, d *schema.ResourceData) interface{} { if v == nil { return nil @@ -373,6 +437,14 @@ func flattenComputeInterconnectAttachmentPrivateInterconnectInfoTag8021q(v inter return v } +func flattenComputeInterconnectAttachmentType(v interface{}, d *schema.ResourceData) interface{} { + return v +} + +func flattenComputeInterconnectAttachmentState(v interface{}, d *schema.ResourceData) interface{} { + return v +} + func flattenComputeInterconnectAttachmentGoogleReferenceId(v interface{}, d *schema.ResourceData) interface{} { return v } @@ -421,6 +493,14 @@ func expandComputeInterconnectAttachmentDescription(v interface{}, d *schema.Res return v, nil } +func expandComputeInterconnectAttachmentEdgeAvailabilityDomain(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandComputeInterconnectAttachmentType(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) { + return v, nil +} + func expandComputeInterconnectAttachmentRouter(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) { f, err := parseRegionalFieldValue("routers", v.(string), "project", "region", "zone", d, config, true) if err != nil { diff --git a/website/docs/r/compute_interconnect_attachment.html.markdown b/website/docs/r/compute_interconnect_attachment.html.markdown index 8de73009..83097671 100644 --- a/website/docs/r/compute_interconnect_attachment.html.markdown +++ b/website/docs/r/compute_interconnect_attachment.html.markdown @@ -47,11 +47,6 @@ resource "google_compute_router" "foobar" { The following arguments are supported: -* `interconnect` - - (Required) - URL of the underlying Interconnect object that this attachment's traffic will - traverse through. - * `router` - (Required) URL of the cloud router to be used for dynamic routing. This router must be in @@ -72,10 +67,30 @@ The following arguments are supported: - - - +* `interconnect` - + (Optional) + URL of the underlying Interconnect object that this attachment's + traffic will traverse through. Required if type is DEDICATED, must not + be set if type is PARTNER. + * `description` - (Optional) An optional description of this resource. +* `edge_availability_domain` - + (Optional) + Desired availability domain for the attachment. Only available for type + PARTNER, at creation time. For improved reliability, customers should + configure a pair of attachments with one per availability domain. The + selected availability domain will be provided to the Partner via the + pairing key so that the provisioned circuit will lie in the specified + domain. If not specified, the value will default to AVAILABILITY_DOMAIN_ANY. + +* `type` - + (Optional) + The type of InterconnectAttachment you wish to create. Defaults to + DEDICATED. + * `candidate_subnets` - (Optional) Up to 16 candidate prefixes that can be used to restrict the allocation @@ -110,10 +125,23 @@ In addition to the arguments listed above, the following computed attributes are IPv4 address + prefix length to be configured on the customer router subinterface for this interconnect attachment. +* `pairing_key` - + [Output only for type PARTNER. Not present for DEDICATED]. The opaque + identifier of an PARTNER attachment used to initiate provisioning with + a selected partner. Of the form "XXXXX/region/domain" + +* `partner_asn` - + [Output only for type PARTNER. Not present for DEDICATED]. Optional + BGP ASN for the router that should be supplied by a layer 3 Partner if + they configured BGP on behalf of the customer. + * `private_interconnect_info` - Information specific to an InterconnectAttachment. This property is populated if the interconnect that this is attached to is of type DEDICATED. Structure is documented below. +* `state` - + [Output Only] The current state of this attachment's functionality. + * `google_reference_id` - Google reference ID, to be used when raising support tickets with Google or otherwise to debug backend connectivity issues.