diff --git a/google/compute_shared_operation.go b/google/compute_shared_operation.go index 86d46072b3f..a8811ee172b 100644 --- a/google/compute_shared_operation.go +++ b/google/compute_shared_operation.go @@ -5,6 +5,25 @@ import ( "google.golang.org/api/compute/v1" ) +func computeSharedOperationWait(config *Config, op interface{}, project string, activity string) error { + return computeSharedOperationWaitTime(config, op, project, 4, activity) +} + +func computeSharedOperationWaitTime(config *Config, op interface{}, project string, minutes int, activity string) error { + if op == nil { + panic("Attempted to wait on an Operation that was nil.") + } + + switch op.(type) { + case *compute.Operation: + return computeOperationWaitTime(config, op.(*compute.Operation), project, activity, minutes) + case *computeBeta.Operation: + return computeBetaOperationWaitGlobalTime(config, op.(*computeBeta.Operation), project, activity, minutes) + default: + panic("Attempted to wait on an Operation of unknown type.") + } +} + func computeSharedOperationWaitZone(config *Config, op interface{}, project string, zone, activity string) error { return computeSharedOperationWaitZoneTime(config, op, project, zone, 4, activity) } diff --git a/google/resource_compute_global_forwarding_rule.go b/google/resource_compute_global_forwarding_rule.go index ead555e69d5..1c4b0754c69 100644 --- a/google/resource_compute_global_forwarding_rule.go +++ b/google/resource_compute_global_forwarding_rule.go @@ -5,9 +5,15 @@ import ( "log" "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" + + computeBeta "google.golang.org/api/compute/v0.beta" "google.golang.org/api/compute/v1" ) +var GlobalForwardingRuleBaseApiVersion = v1 +var GlobalForwardingRuleVersionedFeatures = []Feature{Feature{Version: v0beta, Item: "ip_version"}} + func resourceComputeGlobalForwardingRule() *schema.Resource { return &schema.Resource{ Create: resourceComputeGlobalForwardingRuleCreate, @@ -23,8 +29,9 @@ func resourceComputeGlobalForwardingRule() *schema.Resource { }, "target": &schema.Schema{ - Type: schema.TypeString, - Required: true, + Type: schema.TypeString, + Required: true, + DiffSuppressFunc: compareSelfLinkRelativePaths, }, "description": &schema.Schema{ @@ -53,6 +60,13 @@ func resourceComputeGlobalForwardingRule() *schema.Resource { ForceNew: true, }, + "ip_version": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + ForceNew: true, + ValidateFunc: validation.StringInSlice([]string{"IPV4", "IPV6"}, false), + }, + "project": &schema.Schema{ Type: schema.TypeString, Optional: true, @@ -75,6 +89,7 @@ func resourceComputeGlobalForwardingRule() *schema.Resource { } func resourceComputeGlobalForwardingRuleCreate(d *schema.ResourceData, meta interface{}) error { + computeApiVersion := getComputeApiVersion(d, GlobalForwardingRuleBaseApiVersion, GlobalForwardingRuleVersionedFeatures) config := meta.(*Config) project, err := getProject(d, config) @@ -82,25 +97,46 @@ func resourceComputeGlobalForwardingRuleCreate(d *schema.ResourceData, meta inte return err } - frule := &compute.ForwardingRule{ + frule := &computeBeta.ForwardingRule{ IPAddress: d.Get("ip_address").(string), IPProtocol: d.Get("ip_protocol").(string), + IpVersion: d.Get("ip_version").(string), Description: d.Get("description").(string), Name: d.Get("name").(string), PortRange: d.Get("port_range").(string), Target: d.Get("target").(string), } - op, err := config.clientCompute.GlobalForwardingRules.Insert( - project, frule).Do() - if err != nil { - return fmt.Errorf("Error creating Global Forwarding Rule: %s", err) + var op interface{} + switch computeApiVersion { + case v1: + v1Frule := &compute.ForwardingRule{} + err = Convert(frule, v1Frule) + if err != nil { + return err + } + + op, err = config.clientCompute.GlobalForwardingRules.Insert(project, v1Frule).Do() + if err != nil { + return fmt.Errorf("Error creating Global Forwarding Rule: %s", err) + } + case v0beta: + v0BetaFrule := &computeBeta.ForwardingRule{} + err = Convert(frule, v0BetaFrule) + if err != nil { + return err + } + + op, err = config.clientComputeBeta.GlobalForwardingRules.Insert(project, v0BetaFrule).Do() + if err != nil { + return fmt.Errorf("Error creating Global Forwarding Rule: %s", err) + } } // It probably maybe worked, so store the ID now d.SetId(frule.Name) - err = computeOperationWait(config, op, project, "Creating Global Fowarding Rule") + err = computeSharedOperationWait(config, op, project, "Creating Global Fowarding Rule") if err != nil { return err } @@ -109,6 +145,7 @@ func resourceComputeGlobalForwardingRuleCreate(d *schema.ResourceData, meta inte } func resourceComputeGlobalForwardingRuleUpdate(d *schema.ResourceData, meta interface{}) error { + computeApiVersion := getComputeApiVersionUpdate(d, GlobalForwardingRuleBaseApiVersion, GlobalForwardingRuleVersionedFeatures, []Feature{}) config := meta.(*Config) project, err := getProject(d, config) @@ -119,15 +156,38 @@ func resourceComputeGlobalForwardingRuleUpdate(d *schema.ResourceData, meta inte d.Partial(true) if d.HasChange("target") { - target_name := d.Get("target").(string) - target_ref := &compute.TargetReference{Target: target_name} - op, err := config.clientCompute.GlobalForwardingRules.SetTarget( - project, d.Id(), target_ref).Do() - if err != nil { - return fmt.Errorf("Error updating target: %s", err) + target := d.Get("target").(string) + targetRef := &computeBeta.TargetReference{Target: target} + + var op interface{} + switch computeApiVersion { + case v1: + v1TargetRef := &compute.TargetReference{} + err = Convert(targetRef, v1TargetRef) + if err != nil { + return err + } + + op, err = config.clientCompute.GlobalForwardingRules.SetTarget( + project, d.Id(), v1TargetRef).Do() + if err != nil { + return fmt.Errorf("Error updating target: %s", err) + } + case v0beta: + v0BetaTargetRef := &compute.TargetReference{} + err = Convert(targetRef, v0BetaTargetRef) + if err != nil { + return err + } + + op, err = config.clientCompute.GlobalForwardingRules.SetTarget( + project, d.Id(), v0BetaTargetRef).Do() + if err != nil { + return fmt.Errorf("Error updating target: %s", err) + } } - err = computeOperationWait(config, op, project, "Updating Global Forwarding Rule") + err = computeSharedOperationWait(config, op, project, "Updating Global Forwarding Rule") if err != nil { return err } @@ -141,6 +201,7 @@ func resourceComputeGlobalForwardingRuleUpdate(d *schema.ResourceData, meta inte } func resourceComputeGlobalForwardingRuleRead(d *schema.ResourceData, meta interface{}) error { + computeApiVersion := getComputeApiVersion(d, GlobalForwardingRuleBaseApiVersion, GlobalForwardingRuleVersionedFeatures) config := meta.(*Config) project, err := getProject(d, config) @@ -148,20 +209,40 @@ func resourceComputeGlobalForwardingRuleRead(d *schema.ResourceData, meta interf return err } - frule, err := config.clientCompute.GlobalForwardingRules.Get( - project, d.Id()).Do() - if err != nil { - return handleNotFoundError(err, d, fmt.Sprintf("Global Forwarding Rule %q", d.Get("name").(string))) + frule := &computeBeta.ForwardingRule{} + switch computeApiVersion { + case v1: + v1Frule, err := config.clientCompute.GlobalForwardingRules.Get(project, d.Id()).Do() + if err != nil { + return handleNotFoundError(err, d, fmt.Sprintf("Global Forwarding Rule %q", d.Get("name").(string))) + } + + err = Convert(v1Frule, frule) + if err != nil { + return err + } + case v0beta: + v0BetaFrule, err := config.clientComputeBeta.GlobalForwardingRules.Get(project, d.Id()).Do() + if err != nil { + return handleNotFoundError(err, d, fmt.Sprintf("Global Forwarding Rule %q", d.Get("name").(string))) + } + + err = Convert(v0BetaFrule, frule) + if err != nil { + return err + } } d.Set("ip_address", frule.IPAddress) d.Set("ip_protocol", frule.IPProtocol) - d.Set("self_link", frule.SelfLink) + d.Set("ip_version", frule.IpVersion) + d.Set("self_link", ConvertSelfLinkToV1(frule.SelfLink)) return nil } func resourceComputeGlobalForwardingRuleDelete(d *schema.ResourceData, meta interface{}) error { + computeApiVersion := getComputeApiVersion(d, GlobalForwardingRuleBaseApiVersion, GlobalForwardingRuleVersionedFeatures) config := meta.(*Config) project, err := getProject(d, config) @@ -171,13 +252,21 @@ func resourceComputeGlobalForwardingRuleDelete(d *schema.ResourceData, meta inte // Delete the GlobalForwardingRule log.Printf("[DEBUG] GlobalForwardingRule delete request") - op, err := config.clientCompute.GlobalForwardingRules.Delete( - project, d.Id()).Do() - if err != nil { - return fmt.Errorf("Error deleting GlobalForwardingRule: %s", err) + var op interface{} + switch computeApiVersion { + case v1: + op, err = config.clientCompute.GlobalForwardingRules.Delete(project, d.Id()).Do() + if err != nil { + return fmt.Errorf("Error deleting GlobalForwardingRule: %s", err) + } + case v0beta: + op, err = config.clientComputeBeta.GlobalForwardingRules.Delete(project, d.Id()).Do() + if err != nil { + return fmt.Errorf("Error deleting GlobalForwardingRule: %s", err) + } } - err = computeOperationWait(config, op, project, "Deleting GlobalForwarding Rule") + err = computeSharedOperationWait(config, op, project, "Deleting GlobalForwarding Rule") if err != nil { return err } diff --git a/google/resource_compute_global_forwarding_rule_test.go b/google/resource_compute_global_forwarding_rule_test.go index f81361c7b8e..cc846ab859e 100644 --- a/google/resource_compute_global_forwarding_rule_test.go +++ b/google/resource_compute_global_forwarding_rule_test.go @@ -7,6 +7,8 @@ import ( "github.com/hashicorp/terraform/helper/acctest" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" + + computeBeta "google.golang.org/api/compute/v0.beta" ) func TestAccComputeGlobalForwardingRule_basic(t *testing.T) { @@ -27,6 +29,9 @@ func TestAccComputeGlobalForwardingRule_basic(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckComputeGlobalForwardingRuleExists( "google_compute_global_forwarding_rule.foobar"), + + // Unlike GlobalAddress, IpVersion is "" instead of "IPV4" when this is made with a v1 API. + testAccCheckComputeBetaGlobalForwardingRuleIpVersion("google_compute_global_forwarding_rule.foobar", ""), ), }, }, @@ -65,6 +70,33 @@ func TestAccComputeGlobalForwardingRule_update(t *testing.T) { }) } +func TestAccComputeGlobalForwardingRule_ipv6(t *testing.T) { + var frule computeBeta.ForwardingRule + + fr := fmt.Sprintf("forwardrule-test-%s", acctest.RandString(10)) + proxy1 := fmt.Sprintf("forwardrule-test-%s", acctest.RandString(10)) + proxy2 := fmt.Sprintf("forwardrule-test-%s", acctest.RandString(10)) + backend := fmt.Sprintf("forwardrule-test-%s", acctest.RandString(10)) + hc := fmt.Sprintf("forwardrule-test-%s", acctest.RandString(10)) + urlmap := fmt.Sprintf("forwardrule-test-%s", acctest.RandString(10)) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckComputeGlobalForwardingRuleDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccComputeGlobalForwardingRule_ipv6(fr, proxy1, proxy2, backend, hc, urlmap), + Check: resource.ComposeTestCheckFunc( + testAccCheckComputeBetaGlobalForwardingRuleExists( + "google_compute_global_forwarding_rule.foobar", &frule), + testAccCheckComputeBetaGlobalForwardingRuleIpVersion("google_compute_global_forwarding_rule.foobar", "IPV6"), + ), + }, + }, + }) +} + func testAccCheckComputeGlobalForwardingRuleDestroy(s *terraform.State) error { config := testAccProvider.Meta().(*Config) @@ -110,6 +142,61 @@ func testAccCheckComputeGlobalForwardingRuleExists(n string) resource.TestCheckF } } +func testAccCheckComputeBetaGlobalForwardingRuleExists(n string, frule *computeBeta.ForwardingRule) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found: %s", n) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No ID is set") + } + + config := testAccProvider.Meta().(*Config) + + found, err := config.clientComputeBeta.GlobalForwardingRules.Get( + config.Project, rs.Primary.ID).Do() + if err != nil { + return err + } + + if found.Name != rs.Primary.ID { + return fmt.Errorf("Global Forwarding Rule not found") + } + + *frule = *found + + return nil + } +} + +func testAccCheckComputeBetaGlobalForwardingRuleIpVersion(n, version string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found: %s", n) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No ID is set") + } + + config := testAccProvider.Meta().(*Config) + + frule, err := config.clientComputeBeta.GlobalForwardingRules.Get(config.Project, rs.Primary.ID).Do() + if err != nil { + return err + } + + if frule.IpVersion != version { + return fmt.Errorf("Expected IP version to be %s, got %s", version, frule.IpVersion) + } + + return nil + } +} + func testAccComputeGlobalForwardingRule_basic1(fr, proxy1, proxy2, backend, hc, urlmap string) string { return fmt.Sprintf(` resource "google_compute_global_forwarding_rule" "foobar" { @@ -223,3 +310,61 @@ func testAccComputeGlobalForwardingRule_basic2(fr, proxy1, proxy2, backend, hc, } }`, fr, proxy1, proxy2, backend, hc, urlmap) } + +func testAccComputeGlobalForwardingRule_ipv6(fr, proxy1, proxy2, backend, hc, urlmap string) string { + return fmt.Sprintf(` + resource "google_compute_global_forwarding_rule" "foobar" { + description = "Resource created for Terraform acceptance testing" + ip_protocol = "TCP" + name = "%s" + port_range = "80" + target = "${google_compute_target_http_proxy.foobar1.self_link}" + ip_version = "IPV6" + } + + resource "google_compute_target_http_proxy" "foobar1" { + description = "Resource created for Terraform acceptance testing" + name = "%s" + url_map = "${google_compute_url_map.foobar.self_link}" + } + + resource "google_compute_target_http_proxy" "foobar2" { + description = "Resource created for Terraform acceptance testing" + name = "%s" + url_map = "${google_compute_url_map.foobar.self_link}" + } + + resource "google_compute_backend_service" "foobar" { + name = "%s" + health_checks = ["${google_compute_http_health_check.zero.self_link}"] + } + + resource "google_compute_http_health_check" "zero" { + name = "%s" + request_path = "/" + check_interval_sec = 1 + timeout_sec = 1 + } + + resource "google_compute_url_map" "foobar" { + name = "%s" + default_service = "${google_compute_backend_service.foobar.self_link}" + host_rule { + hosts = ["mysite.com", "myothersite.com"] + path_matcher = "boop" + } + path_matcher { + default_service = "${google_compute_backend_service.foobar.self_link}" + name = "boop" + path_rule { + paths = ["/*"] + service = "${google_compute_backend_service.foobar.self_link}" + } + } + test { + host = "mysite.com" + path = "/*" + service = "${google_compute_backend_service.foobar.self_link}" + } + }`, fr, proxy1, proxy2, backend, hc, urlmap) +} diff --git a/website/docs/r/compute_global_forwarding_rule.html.markdown b/website/docs/r/compute_global_forwarding_rule.html.markdown index 87b266fa414..6bc748a5625 100644 --- a/website/docs/r/compute_global_forwarding_rule.html.markdown +++ b/website/docs/r/compute_global_forwarding_rule.html.markdown @@ -96,6 +96,11 @@ The following arguments are supported: * `project` - (Optional) The project in which the resource belongs. If it is not provided, the provider project is used. +- - - + +* `ip_version` - (Optional, Beta) The IP Version that will be used by this address. +One of `"IPV4"` or `"IPV6"`. + ## Attributes Reference In addition to the arguments listed above, the following computed attributes are