-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
New resource/datasource: SSL Policy (#1247)
* Add SSL Policy to provider * Add resource for SSL Policy * Add SSL Policy data source * Add tests for SSL Policy resource * Add documentation for SSL Policy resource * Add SSL Policy datasource docs * Add test for SSL Policy datasource * Update SSL Policy datasource docs * Make full update for SSL Policy resource * SSL Policy resource test multi-attrib update * Clean up SSL Policy datasource * Set-ify custom_features in SSL Policy resource * Document description ForceNew rationale * Remove refs to TLS_1_3 * Update docs: plural -> singular * Remove extraneous attrs from datasource * Fix update logic for custom_features and add enabled_features * Update docs to include enabled_features * Add test for updating to/from custom_features * Add TLS 1.3 bug link * Add import between multi-step test configs * Move Profile and minTlsVersion back into sslPolicy struct
- Loading branch information
1 parent
a608554
commit 72efdb1
Showing
8 changed files
with
897 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package google | ||
|
||
import ( | ||
"github.com/hashicorp/terraform/helper/schema" | ||
) | ||
|
||
func dataSourceGoogleComputeSslPolicy() *schema.Resource { | ||
// Generate datasource schema from resource | ||
dsSchema := datasourceSchemaFromResourceSchema(resourceComputeSslPolicy().Schema) | ||
|
||
// Set 'Required' schema elements | ||
addRequiredFieldsToSchema(dsSchema, "name") | ||
|
||
// Set 'Optional' schema elements | ||
addOptionalFieldsToSchema(dsSchema, "project") | ||
|
||
return &schema.Resource{ | ||
Read: datasourceComputeSslPolicyRead, | ||
Schema: dsSchema, | ||
} | ||
} | ||
|
||
func datasourceComputeSslPolicyRead(d *schema.ResourceData, meta interface{}) error { | ||
policyName := d.Get("name").(string) | ||
|
||
d.SetId(policyName) | ||
|
||
return resourceComputeSslPolicyRead(d, meta) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
package google | ||
|
||
import ( | ||
"fmt" | ||
"testing" | ||
|
||
"github.com/hashicorp/terraform/helper/acctest" | ||
"github.com/hashicorp/terraform/helper/resource" | ||
"github.com/hashicorp/terraform/terraform" | ||
) | ||
|
||
func TestAccDataSourceGoogleSslPolicy(t *testing.T) { | ||
t.Parallel() | ||
|
||
resource.Test(t, resource.TestCase{ | ||
PreCheck: func() { testAccPreCheck(t) }, | ||
Providers: testAccProviders, | ||
Steps: []resource.TestStep{ | ||
resource.TestStep{ | ||
Config: testAccDataSourceGoogleSslPolicy(), | ||
Check: resource.ComposeTestCheckFunc( | ||
testAccDataSourceGoogleSslPolicyCheck("data.google_compute_ssl_policy.ssl_policy", "google_compute_ssl_policy.foobar"), | ||
), | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func testAccDataSourceGoogleSslPolicyCheck(data_source_name string, resource_name string) resource.TestCheckFunc { | ||
return func(s *terraform.State) error { | ||
ds, ok := s.RootModule().Resources[data_source_name] | ||
if !ok { | ||
return fmt.Errorf("root module has no resource called %s", data_source_name) | ||
} | ||
|
||
rs, ok := s.RootModule().Resources[resource_name] | ||
if !ok { | ||
return fmt.Errorf("can't find %s in state", resource_name) | ||
} | ||
|
||
ds_attr := ds.Primary.Attributes | ||
rs_attr := rs.Primary.Attributes | ||
|
||
ssl_policy_attrs_to_test := []string{ | ||
"id", | ||
"self_link", | ||
"name", | ||
"description", | ||
"min_tls_version", | ||
"profile", | ||
"custom_features", | ||
} | ||
|
||
for _, attr_to_check := range ssl_policy_attrs_to_test { | ||
if ds_attr[attr_to_check] != rs_attr[attr_to_check] { | ||
return fmt.Errorf( | ||
"%s is %s; want %s", | ||
attr_to_check, | ||
ds_attr[attr_to_check], | ||
rs_attr[attr_to_check], | ||
) | ||
} | ||
} | ||
|
||
return nil | ||
} | ||
} | ||
|
||
func testAccDataSourceGoogleSslPolicy() string { | ||
return fmt.Sprintf(` | ||
resource "google_compute_ssl_policy" "foobar" { | ||
name = "%s" | ||
description = "my-description" | ||
min_tls_version = "TLS_1_2" | ||
profile = "MODERN" | ||
} | ||
data "google_compute_ssl_policy" "ssl_policy" { | ||
name = "${google_compute_ssl_policy.foobar.name}" | ||
} | ||
`, acctest.RandomWithPrefix("test-ssl-policy")) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,239 @@ | ||
package google | ||
|
||
import ( | ||
"fmt" | ||
"time" | ||
|
||
"github.com/hashicorp/terraform/helper/schema" | ||
"github.com/hashicorp/terraform/helper/validation" | ||
computeBeta "google.golang.org/api/compute/v0.beta" | ||
) | ||
|
||
func resourceComputeSslPolicy() *schema.Resource { | ||
return &schema.Resource{ | ||
Create: resourceComputeSslPolicyCreate, | ||
Read: resourceComputeSslPolicyRead, | ||
Update: resourceComputeSslPolicyUpdate, | ||
Delete: resourceComputeSslPolicyDelete, | ||
|
||
Importer: &schema.ResourceImporter{ | ||
State: schema.ImportStatePassthrough, | ||
}, | ||
|
||
Timeouts: &schema.ResourceTimeout{ | ||
Create: schema.DefaultTimeout(2 * time.Minute), | ||
Update: schema.DefaultTimeout(2 * time.Minute), | ||
Delete: schema.DefaultTimeout(2 * time.Minute), | ||
}, | ||
|
||
Schema: map[string]*schema.Schema{ | ||
|
||
"name": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
}, | ||
|
||
"custom_features": &schema.Schema{ | ||
Type: schema.TypeSet, | ||
Optional: true, | ||
Elem: &schema.Schema{Type: schema.TypeString}, | ||
Set: schema.HashString, | ||
}, | ||
|
||
"description": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Optional: true, | ||
ForceNew: true, // currently, the beta patch API call does not allow updating the description | ||
}, | ||
|
||
"min_tls_version": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Optional: true, | ||
Default: "TLS_1_0", | ||
// Although compute-gen.go says that TLS_1_3 is a valid value, the API currently (26 Mar 2018) | ||
// responds with an HTTP 200 but doesn't actually create/update the policy. Open bug for this: | ||
// https://issuetracker.google.com/issues/76433946 | ||
ValidateFunc: validation.StringInSlice([]string{"TLS_1_0", "TLS_1_1", "TLS_1_2"}, false), | ||
}, | ||
|
||
"profile": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Optional: true, | ||
Default: "COMPATIBLE", | ||
ValidateFunc: validation.StringInSlice([]string{"COMPATIBLE", "MODERN", "RESTRICTED", "CUSTOM"}, false), | ||
}, | ||
|
||
"project": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Optional: true, | ||
Computed: true, | ||
ForceNew: true, | ||
}, | ||
|
||
"enabled_features": &schema.Schema{ | ||
Type: schema.TypeSet, | ||
Computed: true, | ||
Elem: &schema.Schema{Type: schema.TypeString}, | ||
Set: schema.HashString, | ||
}, | ||
|
||
"fingerprint": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
|
||
"self_link": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
}, | ||
|
||
CustomizeDiff: func(diff *schema.ResourceDiff, v interface{}) error { | ||
profile := diff.Get("profile") | ||
customFeaturesCount := diff.Get("custom_features.#") | ||
|
||
// Validate that policy configs aren't incompatible during all phases | ||
// CUSTOM profile demands non-zero custom_features, and other profiles (i.e., not CUSTOM) demand zero custom_features | ||
if diff.HasChange("profile") || diff.HasChange("custom_features") { | ||
if profile.(string) == "CUSTOM" { | ||
if customFeaturesCount.(int) == 0 { | ||
return fmt.Errorf("Error in SSL Policy %s: the profile is set to %s but no custom_features are set.", diff.Get("name"), profile.(string)) | ||
} | ||
} else { | ||
if customFeaturesCount != 0 { | ||
return fmt.Errorf("Error in SSL Policy %s: the profile is set to %s but using custom_features requires the profile to be CUSTOM.", diff.Get("name"), profile.(string)) | ||
} | ||
} | ||
return nil | ||
} | ||
return nil | ||
}, | ||
} | ||
} | ||
|
||
func resourceComputeSslPolicyCreate(d *schema.ResourceData, meta interface{}) error { | ||
config := meta.(*Config) | ||
|
||
project, err := getProject(d, config) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
sslPolicy := &computeBeta.SslPolicy{ | ||
Name: d.Get("name").(string), | ||
Description: d.Get("description").(string), | ||
Profile: d.Get("profile").(string), | ||
MinTlsVersion: d.Get("min_tls_version").(string), | ||
CustomFeatures: convertStringSet(d.Get("custom_features").(*schema.Set)), | ||
} | ||
|
||
op, err := config.clientComputeBeta.SslPolicies.Insert(project, sslPolicy).Do() | ||
if err != nil { | ||
return fmt.Errorf("Error creating SSL Policy: %s", err) | ||
} | ||
|
||
d.SetId(sslPolicy.Name) | ||
|
||
err = computeSharedOperationWaitTime(config.clientCompute, op, project, int(d.Timeout(schema.TimeoutCreate).Minutes()), "Creating SSL Policy") | ||
if err != nil { | ||
d.SetId("") // if insert fails, remove from state | ||
return err | ||
} | ||
|
||
return resourceComputeSslPolicyRead(d, meta) | ||
} | ||
|
||
func resourceComputeSslPolicyRead(d *schema.ResourceData, meta interface{}) error { | ||
config := meta.(*Config) | ||
|
||
project, err := getProject(d, config) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
name := d.Id() | ||
|
||
sslPolicy, err := config.clientComputeBeta.SslPolicies.Get(project, name).Do() | ||
if err != nil { | ||
return handleNotFoundError(err, d, fmt.Sprintf("SSL Policy %q", name)) | ||
} | ||
|
||
d.Set("name", sslPolicy.Name) | ||
d.Set("description", sslPolicy.Description) | ||
d.Set("min_tls_version", sslPolicy.MinTlsVersion) | ||
d.Set("profile", sslPolicy.Profile) | ||
d.Set("fingerprint", sslPolicy.Fingerprint) | ||
d.Set("project", project) | ||
d.Set("self_link", ConvertSelfLinkToV1(sslPolicy.SelfLink)) | ||
d.Set("enabled_features", convertStringArrToInterface(sslPolicy.EnabledFeatures)) | ||
d.Set("custom_features", convertStringArrToInterface(sslPolicy.CustomFeatures)) | ||
|
||
d.SetId(sslPolicy.Name) | ||
|
||
return nil | ||
} | ||
|
||
func resourceComputeSslPolicyUpdate(d *schema.ResourceData, meta interface{}) error { | ||
|
||
config := meta.(*Config) | ||
|
||
project, err := getProject(d, config) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
name := d.Get("name").(string) | ||
|
||
sslPolicy := &computeBeta.SslPolicy{ | ||
Fingerprint: d.Get("fingerprint").(string), | ||
Profile: d.Get("profile").(string), | ||
MinTlsVersion: d.Get("min_tls_version").(string), | ||
} | ||
|
||
if v, ok := d.Get("custom_features").(*schema.Set); ok { | ||
if v.Len() > 0 { | ||
sslPolicy.CustomFeatures = convertStringSet(v) | ||
} else { | ||
sslPolicy.NullFields = append(sslPolicy.NullFields, "CustomFeatures") | ||
} | ||
} | ||
|
||
op, err := config.clientComputeBeta.SslPolicies.Patch(project, name, sslPolicy).Do() | ||
if err != nil { | ||
return fmt.Errorf("Error updating SSL Policy: %s", err) | ||
} | ||
|
||
err = computeSharedOperationWaitTime(config.clientCompute, op, project, int(d.Timeout(schema.TimeoutUpdate).Minutes()), "Updating SSL Policy") | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return resourceComputeSslPolicyRead(d, meta) | ||
} | ||
|
||
func resourceComputeSslPolicyDelete(d *schema.ResourceData, meta interface{}) error { | ||
|
||
config := meta.(*Config) | ||
|
||
project, err := getProject(d, config) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
name := d.Get("name").(string) | ||
|
||
op, err := config.clientComputeBeta.SslPolicies.Delete(project, name).Do() | ||
if err != nil { | ||
return fmt.Errorf("Error deleting SSL Policy: %s", err) | ||
} | ||
|
||
err = computeSharedOperationWaitTime(config.clientCompute, op, project, int(d.Timeout(schema.TimeoutDelete).Minutes()), "Deleting Subnetwork") | ||
if err != nil { | ||
return err | ||
} | ||
|
||
d.SetId("") | ||
|
||
return nil | ||
} |
Oops, something went wrong.