Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ansible - Regional SSL Certs + Health Check #5913

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .changelog/3210.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:new-resource
`google_compute_region_ssl_certificate`
```
5 changes: 3 additions & 2 deletions google/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -512,9 +512,9 @@ func Provider() terraform.ResourceProvider {
return provider
}

// Generated resources: 108
// Generated resources: 109
// Generated IAM resources: 51
// Total generated resources: 159
// Total generated resources: 160
func ResourceMap() map[string]*schema.Resource {
resourceMap, _ := ResourceMapWithErrors()
return resourceMap
Expand Down Expand Up @@ -590,6 +590,7 @@ func ResourceMapWithErrors() (map[string]*schema.Resource, error) {
"google_compute_router_peer": resourceComputeRouterBgpPeer(),
"google_compute_snapshot": resourceComputeSnapshot(),
"google_compute_ssl_certificate": resourceComputeSslCertificate(),
"google_compute_region_ssl_certificate": resourceComputeRegionSslCertificate(),
"google_compute_reservation": resourceComputeReservation(),
"google_compute_ssl_policy": resourceComputeSslPolicy(),
"google_compute_subnetwork": resourceComputeSubnetwork(),
Expand Down
373 changes: 373 additions & 0 deletions google/resource_compute_region_ssl_certificate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,373 @@
// ----------------------------------------------------------------------------
//
// *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
//
// ----------------------------------------------------------------------------
//
// This file is automatically generated by Magic Modules and manual
// changes will be clobbered when the file is regenerated.
//
// Please read more about how to change this file in
// .github/CONTRIBUTING.md.
//
// ----------------------------------------------------------------------------

package google

import (
"fmt"
"log"
"reflect"
"strconv"
"time"

"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)

func resourceComputeRegionSslCertificate() *schema.Resource {
return &schema.Resource{
Create: resourceComputeRegionSslCertificateCreate,
Read: resourceComputeRegionSslCertificateRead,
Delete: resourceComputeRegionSslCertificateDelete,

Importer: &schema.ResourceImporter{
State: resourceComputeRegionSslCertificateImport,
},

Timeouts: &schema.ResourceTimeout{
Create: schema.DefaultTimeout(4 * time.Minute),
Delete: schema.DefaultTimeout(4 * time.Minute),
},

Schema: map[string]*schema.Schema{
"certificate": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Description: `The certificate in PEM format.
The certificate chain must be no greater than 5 certs long.
The chain must include at least one intermediate cert.`,
Sensitive: true,
},
"private_key": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
DiffSuppressFunc: sha256DiffSuppress,
Description: `The write-only private key in PEM format.`,
Sensitive: true,
},
"description": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Description: `An optional description of this resource.`,
},
"name": {
Type: schema.TypeString,
Computed: true,
Optional: true,
ForceNew: true,
ValidateFunc: validateGCPName,
Description: `Name of the resource. Provided by the client when the resource is
created. The name must be 1-63 characters long, and comply with
RFC1035. Specifically, the name must be 1-63 characters long and match
the regular expression '[a-z]([-a-z0-9]*[a-z0-9])?' which means the
first character must be a lowercase letter, and all following
characters must be a dash, lowercase letter, or digit, except the last
character, which cannot be a dash.


These are in the same namespace as the managed SSL certificates.`,
},
"region": {
Type: schema.TypeString,
Computed: true,
Optional: true,
ForceNew: true,
DiffSuppressFunc: compareSelfLinkOrResourceName,
Description: `The Region in which the created regional ssl certificate should reside.
If it is not provided, the provider region is used.`,
},
"certificate_id": {
Type: schema.TypeInt,
Computed: true,
Description: `The unique identifier for the resource.`,
},
"creation_timestamp": {
Type: schema.TypeString,
Computed: true,
Description: `Creation timestamp in RFC3339 text format.`,
},
"name_prefix": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
ConflictsWith: []string{"name"},
ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) {
// https://cloud.google.com/compute/docs/reference/latest/sslCertificates#resource
// uuid is 26 characters, limit the prefix to 37.
value := v.(string)
if len(value) > 37 {
errors = append(errors, fmt.Errorf(
"%q cannot be longer than 37 characters, name is limited to 63", k))
}
return
},
},
"project": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
},
"self_link": {
Type: schema.TypeString,
Computed: true,
},
},
}
}

func resourceComputeRegionSslCertificateCreate(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)

obj := make(map[string]interface{})
certificateProp, err := expandComputeRegionSslCertificateCertificate(d.Get("certificate"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("certificate"); !isEmptyValue(reflect.ValueOf(certificateProp)) && (ok || !reflect.DeepEqual(v, certificateProp)) {
obj["certificate"] = certificateProp
}
descriptionProp, err := expandComputeRegionSslCertificateDescription(d.Get("description"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("description"); !isEmptyValue(reflect.ValueOf(descriptionProp)) && (ok || !reflect.DeepEqual(v, descriptionProp)) {
obj["description"] = descriptionProp
}
nameProp, err := expandComputeRegionSslCertificateName(d.Get("name"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("name"); !isEmptyValue(reflect.ValueOf(nameProp)) && (ok || !reflect.DeepEqual(v, nameProp)) {
obj["name"] = nameProp
}
privateKeyProp, err := expandComputeRegionSslCertificatePrivateKey(d.Get("private_key"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("private_key"); !isEmptyValue(reflect.ValueOf(privateKeyProp)) && (ok || !reflect.DeepEqual(v, privateKeyProp)) {
obj["privateKey"] = privateKeyProp
}
regionProp, err := expandComputeRegionSslCertificateRegion(d.Get("region"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("region"); !isEmptyValue(reflect.ValueOf(regionProp)) && (ok || !reflect.DeepEqual(v, regionProp)) {
obj["region"] = regionProp
}

url, err := replaceVars(d, config, "{{ComputeBasePath}}projects/{{project}}/regions/{{region}}/sslCertificates")
if err != nil {
return err
}

log.Printf("[DEBUG] Creating new RegionSslCertificate: %#v", obj)
project, err := getProject(d, config)
if err != nil {
return err
}
res, err := sendRequestWithTimeout(config, "POST", project, url, obj, d.Timeout(schema.TimeoutCreate))
if err != nil {
return fmt.Errorf("Error creating RegionSslCertificate: %s", err)
}

// Store the ID now
id, err := replaceVars(d, config, "projects/{{project}}/regions/{{region}}/sslCertificates/{{name}}")
if err != nil {
return fmt.Errorf("Error constructing id: %s", err)
}
d.SetId(id)

err = computeOperationWaitTime(
config, res, project, "Creating RegionSslCertificate",
int(d.Timeout(schema.TimeoutCreate).Minutes()))

if err != nil {
// The resource didn't actually create
d.SetId("")
return fmt.Errorf("Error waiting to create RegionSslCertificate: %s", err)
}

log.Printf("[DEBUG] Finished creating RegionSslCertificate %q: %#v", d.Id(), res)

return resourceComputeRegionSslCertificateRead(d, meta)
}

func resourceComputeRegionSslCertificateRead(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)

url, err := replaceVars(d, config, "{{ComputeBasePath}}projects/{{project}}/regions/{{region}}/sslCertificates/{{name}}")
if err != nil {
return err
}

project, err := getProject(d, config)
if err != nil {
return err
}
res, err := sendRequest(config, "GET", project, url, nil)
if err != nil {
return handleNotFoundError(err, d, fmt.Sprintf("ComputeRegionSslCertificate %q", d.Id()))
}

if err := d.Set("project", project); err != nil {
return fmt.Errorf("Error reading RegionSslCertificate: %s", err)
}

if err := d.Set("certificate", flattenComputeRegionSslCertificateCertificate(res["certificate"], d, config)); err != nil {
return fmt.Errorf("Error reading RegionSslCertificate: %s", err)
}
if err := d.Set("creation_timestamp", flattenComputeRegionSslCertificateCreationTimestamp(res["creationTimestamp"], d, config)); err != nil {
return fmt.Errorf("Error reading RegionSslCertificate: %s", err)
}
if err := d.Set("description", flattenComputeRegionSslCertificateDescription(res["description"], d, config)); err != nil {
return fmt.Errorf("Error reading RegionSslCertificate: %s", err)
}
if err := d.Set("certificate_id", flattenComputeRegionSslCertificateCertificateId(res["id"], d, config)); err != nil {
return fmt.Errorf("Error reading RegionSslCertificate: %s", err)
}
if err := d.Set("name", flattenComputeRegionSslCertificateName(res["name"], d, config)); err != nil {
return fmt.Errorf("Error reading RegionSslCertificate: %s", err)
}
if err := d.Set("region", flattenComputeRegionSslCertificateRegion(res["region"], d, config)); err != nil {
return fmt.Errorf("Error reading RegionSslCertificate: %s", err)
}
if err := d.Set("self_link", ConvertSelfLinkToV1(res["selfLink"].(string))); err != nil {
return fmt.Errorf("Error reading RegionSslCertificate: %s", err)
}

return nil
}

func resourceComputeRegionSslCertificateDelete(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)

project, err := getProject(d, config)
if err != nil {
return err
}

url, err := replaceVars(d, config, "{{ComputeBasePath}}projects/{{project}}/regions/{{region}}/sslCertificates/{{name}}")
if err != nil {
return err
}

var obj map[string]interface{}
log.Printf("[DEBUG] Deleting RegionSslCertificate %q", d.Id())

res, err := sendRequestWithTimeout(config, "DELETE", project, url, obj, d.Timeout(schema.TimeoutDelete))
if err != nil {
return handleNotFoundError(err, d, "RegionSslCertificate")
}

err = computeOperationWaitTime(
config, res, project, "Deleting RegionSslCertificate",
int(d.Timeout(schema.TimeoutDelete).Minutes()))

if err != nil {
return err
}

log.Printf("[DEBUG] Finished deleting RegionSslCertificate %q: %#v", d.Id(), res)
return nil
}

func resourceComputeRegionSslCertificateImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
config := meta.(*Config)
if err := parseImportId([]string{
"projects/(?P<project>[^/]+)/regions/(?P<region>[^/]+)/sslCertificates/(?P<name>[^/]+)",
"(?P<project>[^/]+)/(?P<region>[^/]+)/(?P<name>[^/]+)",
"(?P<region>[^/]+)/(?P<name>[^/]+)",
"(?P<name>[^/]+)",
}, d, config); err != nil {
return nil, err
}

// Replace import id for the resource id
id, err := replaceVars(d, config, "projects/{{project}}/regions/{{region}}/sslCertificates/{{name}}")
if err != nil {
return nil, fmt.Errorf("Error constructing id: %s", err)
}
d.SetId(id)

return []*schema.ResourceData{d}, nil
}

func flattenComputeRegionSslCertificateCertificate(v interface{}, d *schema.ResourceData, config *Config) interface{} {
return v
}

func flattenComputeRegionSslCertificateCreationTimestamp(v interface{}, d *schema.ResourceData, config *Config) interface{} {
return v
}

func flattenComputeRegionSslCertificateDescription(v interface{}, d *schema.ResourceData, config *Config) interface{} {
return v
}

func flattenComputeRegionSslCertificateCertificateId(v interface{}, d *schema.ResourceData, config *Config) interface{} {
// Handles the string fixed64 format
if strVal, ok := v.(string); ok {
if intVal, err := strconv.ParseInt(strVal, 10, 64); err == nil {
return intVal
} // let terraform core handle it if we can't convert the string to an int.
}
return v
}

func flattenComputeRegionSslCertificateName(v interface{}, d *schema.ResourceData, config *Config) interface{} {
return v
}

func flattenComputeRegionSslCertificateRegion(v interface{}, d *schema.ResourceData, config *Config) interface{} {
if v == nil {
return v
}
return NameFromSelfLinkStateFunc(v)
}

func expandComputeRegionSslCertificateCertificate(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
return v, nil
}

func expandComputeRegionSslCertificateDescription(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
return v, nil
}

func expandComputeRegionSslCertificateName(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
var certName string
if v, ok := d.GetOk("name"); ok {
certName = v.(string)
} else if v, ok := d.GetOk("name_prefix"); ok {
certName = resource.PrefixedUniqueId(v.(string))
} else {
certName = resource.UniqueId()
}

// We need to get the {{name}} into schema to set the ID using ReplaceVars
d.Set("name", certName)

return certName, nil
}

func expandComputeRegionSslCertificatePrivateKey(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
return v, nil
}

func expandComputeRegionSslCertificateRegion(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
f, err := parseGlobalFieldValue("regions", v.(string), "project", d, config, true)
if err != nil {
return nil, fmt.Errorf("Invalid value for region: %s", err)
}
return f.RelativeLink(), nil
}
Loading