Merge pull request #3883 from lwander/f-gcp-https-health-checks

provider/google: HTTPS Health Checks Resource + Tests & Documentation
This commit is contained in:
James Nugent 2015-11-12 10:02:39 -06:00
commit cbbe06388f
5 changed files with 460 additions and 0 deletions

View File

@ -43,6 +43,7 @@ func Provider() terraform.ResourceProvider {
"google_compute_global_address": resourceComputeGlobalAddress(), "google_compute_global_address": resourceComputeGlobalAddress(),
"google_compute_global_forwarding_rule": resourceComputeGlobalForwardingRule(), "google_compute_global_forwarding_rule": resourceComputeGlobalForwardingRule(),
"google_compute_http_health_check": resourceComputeHttpHealthCheck(), "google_compute_http_health_check": resourceComputeHttpHealthCheck(),
"google_compute_https_health_check": resourceComputeHttpsHealthCheck(),
"google_compute_instance": resourceComputeInstance(), "google_compute_instance": resourceComputeInstance(),
"google_compute_instance_group_manager": resourceComputeInstanceGroupManager(), "google_compute_instance_group_manager": resourceComputeInstanceGroupManager(),
"google_compute_instance_template": resourceComputeInstanceTemplate(), "google_compute_instance_template": resourceComputeInstanceTemplate(),

View File

@ -0,0 +1,227 @@
package google
import (
"fmt"
"log"
"github.com/hashicorp/terraform/helper/schema"
"google.golang.org/api/compute/v1"
"google.golang.org/api/googleapi"
)
func resourceComputeHttpsHealthCheck() *schema.Resource {
return &schema.Resource{
Create: resourceComputeHttpsHealthCheckCreate,
Read: resourceComputeHttpsHealthCheckRead,
Delete: resourceComputeHttpsHealthCheckDelete,
Update: resourceComputeHttpsHealthCheckUpdate,
Schema: map[string]*schema.Schema{
"check_interval_sec": &schema.Schema{
Type: schema.TypeInt,
Optional: true,
Default: 5,
},
"description": &schema.Schema{
Type: schema.TypeString,
Optional: true,
},
"healthy_threshold": &schema.Schema{
Type: schema.TypeInt,
Optional: true,
Default: 2,
},
"host": &schema.Schema{
Type: schema.TypeString,
Optional: true,
},
"name": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"port": &schema.Schema{
Type: schema.TypeInt,
Optional: true,
Default: 443,
},
"request_path": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Default: "/",
},
"self_link": &schema.Schema{
Type: schema.TypeString,
Computed: true,
},
"timeout_sec": &schema.Schema{
Type: schema.TypeInt,
Optional: true,
Default: 5,
},
"unhealthy_threshold": &schema.Schema{
Type: schema.TypeInt,
Optional: true,
Default: 2,
},
},
}
}
func resourceComputeHttpsHealthCheckCreate(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
// Build the parameter
hchk := &compute.HttpsHealthCheck{
Name: d.Get("name").(string),
}
// Optional things
if v, ok := d.GetOk("description"); ok {
hchk.Description = v.(string)
}
if v, ok := d.GetOk("host"); ok {
hchk.Host = v.(string)
}
if v, ok := d.GetOk("request_path"); ok {
hchk.RequestPath = v.(string)
}
if v, ok := d.GetOk("check_interval_sec"); ok {
hchk.CheckIntervalSec = int64(v.(int))
}
if v, ok := d.GetOk("healthy_threshold"); ok {
hchk.HealthyThreshold = int64(v.(int))
}
if v, ok := d.GetOk("port"); ok {
hchk.Port = int64(v.(int))
}
if v, ok := d.GetOk("timeout_sec"); ok {
hchk.TimeoutSec = int64(v.(int))
}
if v, ok := d.GetOk("unhealthy_threshold"); ok {
hchk.UnhealthyThreshold = int64(v.(int))
}
log.Printf("[DEBUG] HttpsHealthCheck insert request: %#v", hchk)
op, err := config.clientCompute.HttpsHealthChecks.Insert(
config.Project, hchk).Do()
if err != nil {
return fmt.Errorf("Error creating HttpsHealthCheck: %s", err)
}
// It probably maybe worked, so store the ID now
d.SetId(hchk.Name)
err = computeOperationWaitGlobal(config, op, "Creating Https Health Check")
if err != nil {
return err
}
return resourceComputeHttpsHealthCheckRead(d, meta)
}
func resourceComputeHttpsHealthCheckUpdate(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
// Build the parameter
hchk := &compute.HttpsHealthCheck{
Name: d.Get("name").(string),
}
// Optional things
if v, ok := d.GetOk("description"); ok {
hchk.Description = v.(string)
}
if v, ok := d.GetOk("host"); ok {
hchk.Host = v.(string)
}
if v, ok := d.GetOk("request_path"); ok {
hchk.RequestPath = v.(string)
}
if v, ok := d.GetOk("check_interval_sec"); ok {
hchk.CheckIntervalSec = int64(v.(int))
}
if v, ok := d.GetOk("healthy_threshold"); ok {
hchk.HealthyThreshold = int64(v.(int))
}
if v, ok := d.GetOk("port"); ok {
hchk.Port = int64(v.(int))
}
if v, ok := d.GetOk("timeout_sec"); ok {
hchk.TimeoutSec = int64(v.(int))
}
if v, ok := d.GetOk("unhealthy_threshold"); ok {
hchk.UnhealthyThreshold = int64(v.(int))
}
log.Printf("[DEBUG] HttpsHealthCheck patch request: %#v", hchk)
op, err := config.clientCompute.HttpsHealthChecks.Patch(
config.Project, hchk.Name, hchk).Do()
if err != nil {
return fmt.Errorf("Error patching HttpsHealthCheck: %s", err)
}
// It probably maybe worked, so store the ID now
d.SetId(hchk.Name)
err = computeOperationWaitGlobal(config, op, "Updating Https Health Check")
if err != nil {
return err
}
return resourceComputeHttpsHealthCheckRead(d, meta)
}
func resourceComputeHttpsHealthCheckRead(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
hchk, err := config.clientCompute.HttpsHealthChecks.Get(
config.Project, d.Id()).Do()
if err != nil {
if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 404 {
// The resource doesn't exist anymore
d.SetId("")
return nil
}
return fmt.Errorf("Error reading HttpsHealthCheck: %s", err)
}
d.Set("host", hchk.Host)
d.Set("request_path", hchk.RequestPath)
d.Set("check_interval_sec", hchk.CheckIntervalSec)
d.Set("health_threshold", hchk.HealthyThreshold)
d.Set("port", hchk.Port)
d.Set("timeout_sec", hchk.TimeoutSec)
d.Set("unhealthy_threshold", hchk.UnhealthyThreshold)
d.Set("self_link", hchk.SelfLink)
return nil
}
func resourceComputeHttpsHealthCheckDelete(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
// Delete the HttpsHealthCheck
op, err := config.clientCompute.HttpsHealthChecks.Delete(
config.Project, d.Id()).Do()
if err != nil {
return fmt.Errorf("Error deleting HttpsHealthCheck: %s", err)
}
err = computeOperationWaitGlobal(config, op, "Deleting Https Health Check")
if err != nil {
return err
}
d.SetId("")
return nil
}

View File

@ -0,0 +1,171 @@
package google
import (
"fmt"
"testing"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
"google.golang.org/api/compute/v1"
)
func TestAccComputeHttpsHealthCheck_basic(t *testing.T) {
var healthCheck compute.HttpsHealthCheck
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckComputeHttpsHealthCheckDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccComputeHttpsHealthCheck_basic,
Check: resource.ComposeTestCheckFunc(
testAccCheckComputeHttpsHealthCheckExists(
"google_compute_https_health_check.foobar", &healthCheck),
testAccCheckComputeHttpsHealthCheckRequestPath(
"/health_check", &healthCheck),
testAccCheckComputeHttpsHealthCheckThresholds(
3, 3, &healthCheck),
),
},
},
})
}
func TestAccComputeHttpsHealthCheck_update(t *testing.T) {
var healthCheck compute.HttpsHealthCheck
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckComputeHttpsHealthCheckDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccComputeHttpsHealthCheck_update1,
Check: resource.ComposeTestCheckFunc(
testAccCheckComputeHttpsHealthCheckExists(
"google_compute_https_health_check.foobar", &healthCheck),
testAccCheckComputeHttpsHealthCheckRequestPath(
"/not_default", &healthCheck),
testAccCheckComputeHttpsHealthCheckThresholds(
2, 2, &healthCheck),
),
},
resource.TestStep{
Config: testAccComputeHttpsHealthCheck_update2,
Check: resource.ComposeTestCheckFunc(
testAccCheckComputeHttpsHealthCheckExists(
"google_compute_https_health_check.foobar", &healthCheck),
testAccCheckComputeHttpsHealthCheckRequestPath(
"/", &healthCheck),
testAccCheckComputeHttpsHealthCheckThresholds(
10, 10, &healthCheck),
),
},
},
})
}
func testAccCheckComputeHttpsHealthCheckDestroy(s *terraform.State) error {
config := testAccProvider.Meta().(*Config)
for _, rs := range s.RootModule().Resources {
if rs.Type != "google_compute_https_health_check" {
continue
}
_, err := config.clientCompute.HttpsHealthChecks.Get(
config.Project, rs.Primary.ID).Do()
if err == nil {
return fmt.Errorf("HttpsHealthCheck still exists")
}
}
return nil
}
func testAccCheckComputeHttpsHealthCheckExists(n string, healthCheck *compute.HttpsHealthCheck) 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.clientCompute.HttpsHealthChecks.Get(
config.Project, rs.Primary.ID).Do()
if err != nil {
return err
}
if found.Name != rs.Primary.ID {
return fmt.Errorf("HttpsHealthCheck not found")
}
*healthCheck = *found
return nil
}
}
func testAccCheckComputeHttpsHealthCheckRequestPath(path string, healthCheck *compute.HttpsHealthCheck) resource.TestCheckFunc {
return func(s *terraform.State) error {
if healthCheck.RequestPath != path {
return fmt.Errorf("RequestPath doesn't match: expected %s, got %s", path, healthCheck.RequestPath)
}
return nil
}
}
func testAccCheckComputeHttpsHealthCheckThresholds(healthy, unhealthy int64, healthCheck *compute.HttpsHealthCheck) resource.TestCheckFunc {
return func(s *terraform.State) error {
if healthCheck.HealthyThreshold != healthy {
return fmt.Errorf("HealthyThreshold doesn't match: expected %d, got %d", healthy, healthCheck.HealthyThreshold)
}
if healthCheck.UnhealthyThreshold != unhealthy {
return fmt.Errorf("UnhealthyThreshold doesn't match: expected %d, got %d", unhealthy, healthCheck.UnhealthyThreshold)
}
return nil
}
}
const testAccComputeHttpsHealthCheck_basic = `
resource "google_compute_https_health_check" "foobar" {
check_interval_sec = 3
description = "Resource created for Terraform acceptance testing"
healthy_threshold = 3
host = "foobar"
name = "terraform-test"
port = "80"
request_path = "/health_check"
timeout_sec = 2
unhealthy_threshold = 3
}
`
const testAccComputeHttpsHealthCheck_update1 = `
resource "google_compute_https_health_check" "foobar" {
name = "terraform-test"
description = "Resource created for Terraform acceptance testing"
request_path = "/not_default"
}
`
/* Change description, restore request_path to default, and change
* thresholds from defaults */
const testAccComputeHttpsHealthCheck_update2 = `
resource "google_compute_https_health_check" "foobar" {
name = "terraform-test"
description = "Resource updated for Terraform acceptance testing"
healthy_threshold = 10
unhealthy_threshold = 10
}
`

View File

@ -0,0 +1,57 @@
---
layout: "google"
page_title: "Google: google_compute_https_health_check"
sidebar_current: "docs-google-compute-https-health-check"
description: |-
Manages an HTTPS Health Check within GCE.
---
# google\_compute\_https\_health\_check
Manages an HTTPS health check within GCE. This is used to monitor instances
behind load balancers. Timeouts or HTTPS errors cause the instance to be
removed from the pool. For more information, see [the official
documentation](https://cloud.google.com/compute/docs/load-balancing/health-checks)
and
[API](https://cloud.google.com/compute/docs/reference/latest/httpsHealthChecks).
## Example Usage
```
resource "google_compute_https_health_check" "default" {
name = "test"
request_path = "/health_check"
check_interval_sec = 1
timeout_sec = 1
}
```
## Argument Reference
The following arguments are supported:
* `check_interval_sec` - (Optional) How often to poll each instance (default 5).
* `description` - (Optional) Textual description field.
* `healthy_threshold` - (Optional) Consecutive successes required (default 2).
* `host` - (Optional) HTTPS host header field (default instance's public ip).
* `name` - (Required) A unique name for the resource, required by GCE.
Changing this forces a new resource to be created.
* `port` - (Optional) TCP port to connect to (default 443).
* `request_path` - (Optional) URL path to query (default /).
* `timeout_sec` - (Optional) How long before declaring failure (default 5).
* `unhealthy_threshold` - (Optional) Consecutive failures required (default 2).
## Attributes Reference
The following attributes are exported:
* `self_link` - The URL of the created resource.

View File

@ -49,6 +49,10 @@
<a href="/docs/providers/google/r/compute_http_health_check.html">google_compute_http_health_check</a> <a href="/docs/providers/google/r/compute_http_health_check.html">google_compute_http_health_check</a>
</li> </li>
<li<%= sidebar_current("docs-google-compute-https-health-check") %>>
<a href="/docs/providers/google/r/compute_https_health_check.html">google_compute_https_health_check</a>
</li>
<li<%= sidebar_current("docs-google-compute-instance") %>> <li<%= sidebar_current("docs-google-compute-instance") %>>
<a href="/docs/providers/google/r/compute_instance.html">google_compute_instance</a> <a href="/docs/providers/google/r/compute_instance.html">google_compute_instance</a>
</li> </li>