mirror of
https://github.com/letic/terraform-provider-google.git
synced 2024-10-03 01:01:06 +00:00
add support for security policies in backend services (#1243)
This commit is contained in:
parent
fde96ca9d9
commit
790711c649
@ -62,6 +62,10 @@ func ParseInstanceGroupFieldValue(instanceGroup string, d TerraformResourceData,
|
||||
return parseZonalFieldValue("instanceGroups", instanceGroup, "project", "zone", d, config, false)
|
||||
}
|
||||
|
||||
func ParseSecurityPolicyFieldValue(securityPolicy string, d TerraformResourceData, config *Config) (*GlobalFieldValue, error) {
|
||||
return parseGlobalFieldValue("securityPolicies", securityPolicy, "project", d, config, true)
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Base helpers used to create helpers for specific fields.
|
||||
// ------------------------------------------------------------
|
||||
|
@ -6,10 +6,15 @@ import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/hashicorp/errwrap"
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
"google.golang.org/api/compute/v1"
|
||||
computeBeta "google.golang.org/api/compute/v0.beta"
|
||||
compute "google.golang.org/api/compute/v1"
|
||||
)
|
||||
|
||||
var BackendServiceBaseApiVersion = v1
|
||||
var BackendServiceVersionedFeatures = []Feature{Feature{Version: v0beta, Item: "security_policy"}}
|
||||
|
||||
func resourceComputeBackendService() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
Create: resourceComputeBackendServiceCreate,
|
||||
@ -32,7 +37,7 @@ func resourceComputeBackendService() *schema.Resource {
|
||||
"health_checks": &schema.Schema{
|
||||
Type: schema.TypeSet,
|
||||
Elem: &schema.Schema{Type: schema.TypeString},
|
||||
Set: schema.HashString,
|
||||
Set: selfLinkRelativePathHash,
|
||||
Required: true,
|
||||
MinItems: 1,
|
||||
MaxItems: 1,
|
||||
@ -191,6 +196,12 @@ func resourceComputeBackendService() *schema.Resource {
|
||||
Removed: "region has been removed as it was never used. For internal load balancing, use google_compute_region_backend_service",
|
||||
},
|
||||
|
||||
"security_policy": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
DiffSuppressFunc: compareSelfLinkOrResourceName,
|
||||
},
|
||||
|
||||
"self_link": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
@ -250,10 +261,26 @@ func resourceComputeBackendServiceCreate(d *schema.ResourceData, meta interface{
|
||||
return waitErr
|
||||
}
|
||||
|
||||
if v, ok := d.GetOk("security_policy"); ok {
|
||||
pol, err := ParseSecurityPolicyFieldValue(v.(string), d, config)
|
||||
op, err := config.clientComputeBeta.BackendServices.SetSecurityPolicy(
|
||||
project, service.Name, &computeBeta.SecurityPolicyReference{
|
||||
SecurityPolicy: pol.RelativeLink(),
|
||||
}).Do()
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Error setting Backend Service security policy: {{err}}", err)
|
||||
}
|
||||
waitErr := computeSharedOperationWait(config.clientCompute, op, project, "Adding Backend Service Security Policy")
|
||||
if waitErr != nil {
|
||||
return waitErr
|
||||
}
|
||||
}
|
||||
|
||||
return resourceComputeBackendServiceRead(d, meta)
|
||||
}
|
||||
|
||||
func resourceComputeBackendServiceRead(d *schema.ResourceData, meta interface{}) error {
|
||||
computeApiVersion := getComputeApiVersion(d, BackendServiceBaseApiVersion, BackendServiceVersionedFeatures)
|
||||
config := meta.(*Config)
|
||||
|
||||
project, err := getProject(d, config)
|
||||
@ -261,10 +288,25 @@ func resourceComputeBackendServiceRead(d *schema.ResourceData, meta interface{})
|
||||
return err
|
||||
}
|
||||
|
||||
service, err := config.clientCompute.BackendServices.Get(
|
||||
project, d.Id()).Do()
|
||||
if err != nil {
|
||||
return handleNotFoundError(err, d, fmt.Sprintf("Backend Service %q", d.Get("name").(string)))
|
||||
service := &computeBeta.BackendService{}
|
||||
switch computeApiVersion {
|
||||
case v1:
|
||||
v1Service, err := config.clientCompute.BackendServices.Get(
|
||||
project, d.Id()).Do()
|
||||
if err != nil {
|
||||
return handleNotFoundError(err, d, fmt.Sprintf("Backend Service %q", d.Get("name").(string)))
|
||||
}
|
||||
err = Convert(v1Service, service)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case v0beta:
|
||||
var err error
|
||||
service, err = config.clientComputeBeta.BackendServices.Get(
|
||||
project, d.Id()).Do()
|
||||
if err != nil {
|
||||
return handleNotFoundError(err, d, fmt.Sprintf("Backend Service %q", d.Get("name").(string)))
|
||||
}
|
||||
}
|
||||
|
||||
d.Set("name", service.Name)
|
||||
@ -284,6 +326,7 @@ func resourceComputeBackendServiceRead(d *schema.ResourceData, meta interface{})
|
||||
if err := d.Set("cdn_policy", flattenCdnPolicy(service.CdnPolicy)); err != nil {
|
||||
return err
|
||||
}
|
||||
d.Set("security_policy", service.SecurityPolicy)
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -309,13 +352,29 @@ func resourceComputeBackendServiceUpdate(d *schema.ResourceData, meta interface{
|
||||
return fmt.Errorf("Error updating backend service: %s", err)
|
||||
}
|
||||
|
||||
d.SetId(service.Name)
|
||||
|
||||
err = computeOperationWait(config.clientCompute, op, project, "Updating Backend Service")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if d.HasChange("security_policy") {
|
||||
pol, err := ParseSecurityPolicyFieldValue(d.Get("security_policy").(string), d, config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
op, err := config.clientComputeBeta.BackendServices.SetSecurityPolicy(
|
||||
project, service.Name, &computeBeta.SecurityPolicyReference{
|
||||
SecurityPolicy: pol.RelativeLink(),
|
||||
}).Do()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
waitErr := computeSharedOperationWait(config.clientCompute, op, project, "Adding Backend Service Security Policy")
|
||||
if waitErr != nil {
|
||||
return waitErr
|
||||
}
|
||||
}
|
||||
|
||||
return resourceComputeBackendServiceRead(d, meta)
|
||||
}
|
||||
|
||||
@ -359,7 +418,7 @@ func expandIap(configured []interface{}) *compute.BackendServiceIAP {
|
||||
return nil
|
||||
}
|
||||
|
||||
func flattenIap(iap *compute.BackendServiceIAP) []map[string]interface{} {
|
||||
func flattenIap(iap *computeBeta.BackendServiceIAP) []map[string]interface{} {
|
||||
result := make([]map[string]interface{}, 0, 1)
|
||||
if iap == nil || !iap.Enabled {
|
||||
return result
|
||||
@ -421,7 +480,7 @@ func expandBackends(configured []interface{}) ([]*compute.Backend, error) {
|
||||
return backends, nil
|
||||
}
|
||||
|
||||
func flattenBackends(backends []*compute.Backend) []map[string]interface{} {
|
||||
func flattenBackends(backends []*computeBeta.Backend) []map[string]interface{} {
|
||||
result := make([]map[string]interface{}, 0, len(backends))
|
||||
|
||||
for _, b := range backends {
|
||||
@ -544,7 +603,7 @@ func expandCdnPolicy(configured []interface{}) *compute.BackendServiceCdnPolicy
|
||||
}
|
||||
}
|
||||
|
||||
func flattenCdnPolicy(pol *compute.BackendServiceCdnPolicy) []map[string]interface{} {
|
||||
func flattenCdnPolicy(pol *computeBeta.BackendServiceCdnPolicy) []map[string]interface{} {
|
||||
result := []map[string]interface{}{}
|
||||
if pol == nil || pol.CacheKeyPolicy == nil {
|
||||
return result
|
||||
|
@ -2,6 +2,7 @@ package google
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/terraform/helper/acctest"
|
||||
@ -300,6 +301,31 @@ func TestAccComputeBackendService_withCdnPolicy(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestAccComputeBackendService_withSecurityPolicy(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
serviceName := fmt.Sprintf("tf-test-%s", acctest.RandString(10))
|
||||
checkName := fmt.Sprintf("tf-test-%s", acctest.RandString(10))
|
||||
polName := fmt.Sprintf("tf-test-%s", acctest.RandString(10))
|
||||
var svc compute.BackendService
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckComputeBackendServiceDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
resource.TestStep{
|
||||
Config: testAccComputeBackendService_withSecurityPolicy(serviceName, checkName, polName),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckComputeBackendServiceExists(
|
||||
"google_compute_backend_service.foobar", &svc),
|
||||
resource.TestMatchResourceAttr("google_compute_backend_service.foobar", "security_policy", regexp.MustCompile(polName)),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func testAccCheckComputeBackendServiceDestroy(s *terraform.State) error {
|
||||
config := testAccProvider.Meta().(*Config)
|
||||
|
||||
@ -715,3 +741,25 @@ resource "google_compute_http_health_check" "zero" {
|
||||
}
|
||||
`, serviceName, checkName)
|
||||
}
|
||||
|
||||
func testAccComputeBackendService_withSecurityPolicy(serviceName, checkName, polName string) string {
|
||||
return fmt.Sprintf(`
|
||||
resource "google_compute_backend_service" "foobar" {
|
||||
name = "%s"
|
||||
health_checks = ["${google_compute_http_health_check.zero.self_link}"]
|
||||
security_policy = "${google_compute_security_policy.policy.self_link}"
|
||||
}
|
||||
|
||||
resource "google_compute_http_health_check" "zero" {
|
||||
name = "%s"
|
||||
request_path = "/"
|
||||
check_interval_sec = 1
|
||||
timeout_sec = 1
|
||||
}
|
||||
|
||||
resource "google_compute_security_policy" "policy" {
|
||||
name = "%s"
|
||||
description = "basic security policy"
|
||||
}
|
||||
`, serviceName, checkName, polName)
|
||||
}
|
||||
|
@ -81,6 +81,9 @@ The following arguments are supported:
|
||||
|
||||
* `cdn_policy` - (Optional) Cloud CDN configuration for this BackendService. Structure is documented below.
|
||||
|
||||
* `connection_draining_timeout_sec` - (Optional) Time for which instance will be drained (not accept new connections,
|
||||
but still work to finish started ones). Defaults to `300`.
|
||||
|
||||
* `description` - (Optional) The textual description for the backend service.
|
||||
|
||||
* `enable_cdn` - (Optional) Whether or not to enable the Cloud CDN on the backend service.
|
||||
@ -94,6 +97,9 @@ The following arguments are supported:
|
||||
* `protocol` - (Optional) The protocol for incoming requests. Defaults to
|
||||
`HTTP`.
|
||||
|
||||
* `security_policy` - (Optional, [Beta](/docs/providers/google/index.html#beta-features)) Name or URI of a
|
||||
[security policy](https://cloud.google.com/armor/docs/security-policy-concepts) to add to the backend service.
|
||||
|
||||
* `session_affinity` - (Optional) How to distribute load. Options are `NONE` (no
|
||||
affinity), `CLIENT_IP` (hash of the source/dest addresses / ports), and
|
||||
`GENERATED_COOKIE` (distribute load using a generated session cookie).
|
||||
@ -101,9 +107,6 @@ The following arguments are supported:
|
||||
* `timeout_sec` - (Optional) The number of secs to wait for a backend to respond
|
||||
to a request before considering the request failed. Defaults to `30`.
|
||||
|
||||
* `connection_draining_timeout_sec` - (Optional) Time for which instance will be drained (not accept new connections,
|
||||
but still work to finish started ones). Defaults to `300`.
|
||||
|
||||
The `backend` block supports:
|
||||
|
||||
* `group` - (Required) The name or URI of a Compute Engine instance group
|
||||
|
Loading…
Reference in New Issue
Block a user