Skip to content

Commit

Permalink
DNSSec on Managed Zones (#737)
Browse files Browse the repository at this point in the history
Signed-off-by: Modular Magician <[email protected]>
  • Loading branch information
modular-magician authored and chrisst committed May 22, 2019
1 parent f5e6612 commit 5543452
Show file tree
Hide file tree
Showing 3 changed files with 304 additions and 0 deletions.
255 changes: 255 additions & 0 deletions google-beta/resource_dns_managed_zone.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"fmt"
"log"
"reflect"
"strconv"
"time"

"github.com/hashicorp/terraform/helper/hashcode"
Expand Down Expand Up @@ -59,6 +60,66 @@ func resourceDnsManagedZone() *schema.Resource {
Optional: true,
Default: "Managed by Terraform",
},
"dnssec_config": {
Type: schema.TypeList,
Optional: true,
ForceNew: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"default_key_specs": {
Type: schema.TypeList,
Optional: true,
ForceNew: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"algorithm": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
ValidateFunc: validation.StringInSlice([]string{"ecdsap256sha256", "ecdsap384sha384", "rsasha1", "rsasha256", "rsasha512", ""}, false),
},
"key_length": {
Type: schema.TypeInt,
Optional: true,
ForceNew: true,
},
"key_type": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
ValidateFunc: validation.StringInSlice([]string{"keySigning", "zoneSigning", ""}, false),
},
"kind": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Default: "dns#dnsKeySpec",
},
},
},
},
"kind": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Default: "dns#managedZoneDnsSecConfig",
},
"non_existence": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
ValidateFunc: validation.StringInSlice([]string{"nsec", "nsec3", ""}, false),
},
"state": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
ValidateFunc: validation.StringInSlice([]string{"off", "on", "transfer", ""}, false),
},
},
},
},
"forwarding_config": {
Type: schema.TypeList,
Optional: true,
Expand Down Expand Up @@ -196,6 +257,12 @@ func resourceDnsManagedZoneCreate(d *schema.ResourceData, meta interface{}) erro
} else if v, ok := d.GetOkExists("dns_name"); !isEmptyValue(reflect.ValueOf(dnsNameProp)) && (ok || !reflect.DeepEqual(v, dnsNameProp)) {
obj["dnsName"] = dnsNameProp
}
dnssecConfigProp, err := expandDnsManagedZoneDnssecConfig(d.Get("dnssec_config"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("dnssec_config"); !isEmptyValue(reflect.ValueOf(dnssecConfigProp)) && (ok || !reflect.DeepEqual(v, dnssecConfigProp)) {
obj["dnssecConfig"] = dnssecConfigProp
}
nameProp, err := expandDnsManagedZoneName(d.Get("name"), d, config)
if err != nil {
return err
Expand Down Expand Up @@ -283,6 +350,9 @@ func resourceDnsManagedZoneRead(d *schema.ResourceData, meta interface{}) error
if err := d.Set("dns_name", flattenDnsManagedZoneDnsName(res["dnsName"], d)); err != nil {
return fmt.Errorf("Error reading ManagedZone: %s", err)
}
if err := d.Set("dnssec_config", flattenDnsManagedZoneDnssecConfig(res["dnssecConfig"], d)); err != nil {
return fmt.Errorf("Error reading ManagedZone: %s", err)
}
if err := d.Set("name", flattenDnsManagedZoneName(res["name"], d)); err != nil {
return fmt.Errorf("Error reading ManagedZone: %s", err)
}
Expand Down Expand Up @@ -410,6 +480,80 @@ func flattenDnsManagedZoneDnsName(v interface{}, d *schema.ResourceData) interfa
return v
}

func flattenDnsManagedZoneDnssecConfig(v interface{}, d *schema.ResourceData) interface{} {
if v == nil {
return nil
}
original := v.(map[string]interface{})
if len(original) == 0 {
return nil
}
transformed := make(map[string]interface{})
transformed["kind"] =
flattenDnsManagedZoneDnssecConfigKind(original["kind"], d)
transformed["non_existence"] =
flattenDnsManagedZoneDnssecConfigNonExistence(original["nonExistence"], d)
transformed["state"] =
flattenDnsManagedZoneDnssecConfigState(original["state"], d)
transformed["default_key_specs"] =
flattenDnsManagedZoneDnssecConfigDefaultKeySpecs(original["defaultKeySpecs"], d)
return []interface{}{transformed}
}
func flattenDnsManagedZoneDnssecConfigKind(v interface{}, d *schema.ResourceData) interface{} {
return v
}

func flattenDnsManagedZoneDnssecConfigNonExistence(v interface{}, d *schema.ResourceData) interface{} {
return v
}

func flattenDnsManagedZoneDnssecConfigState(v interface{}, d *schema.ResourceData) interface{} {
return v
}

func flattenDnsManagedZoneDnssecConfigDefaultKeySpecs(v interface{}, d *schema.ResourceData) interface{} {
if v == nil {
return v
}
l := v.([]interface{})
transformed := make([]interface{}, 0, len(l))
for _, raw := range l {
original := raw.(map[string]interface{})
if len(original) < 1 {
// Do not include empty json objects coming back from the api
continue
}
transformed = append(transformed, map[string]interface{}{
"algorithm": flattenDnsManagedZoneDnssecConfigDefaultKeySpecsAlgorithm(original["algorithm"], d),
"key_length": flattenDnsManagedZoneDnssecConfigDefaultKeySpecsKeyLength(original["keyLength"], d),
"key_type": flattenDnsManagedZoneDnssecConfigDefaultKeySpecsKeyType(original["keyType"], d),
"kind": flattenDnsManagedZoneDnssecConfigDefaultKeySpecsKind(original["kind"], d),
})
}
return transformed
}
func flattenDnsManagedZoneDnssecConfigDefaultKeySpecsAlgorithm(v interface{}, d *schema.ResourceData) interface{} {
return v
}

func flattenDnsManagedZoneDnssecConfigDefaultKeySpecsKeyLength(v interface{}, d *schema.ResourceData) 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 flattenDnsManagedZoneDnssecConfigDefaultKeySpecsKeyType(v interface{}, d *schema.ResourceData) interface{} {
return v
}

func flattenDnsManagedZoneDnssecConfigDefaultKeySpecsKind(v interface{}, d *schema.ResourceData) interface{} {
return v
}

func flattenDnsManagedZoneName(v interface{}, d *schema.ResourceData) interface{} {
return v
}
Expand Down Expand Up @@ -553,6 +697,117 @@ func expandDnsManagedZoneDnsName(v interface{}, d TerraformResourceData, config
return v, nil
}

func expandDnsManagedZoneDnssecConfig(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
l := v.([]interface{})
if len(l) == 0 || l[0] == nil {
return nil, nil
}
raw := l[0]
original := raw.(map[string]interface{})
transformed := make(map[string]interface{})

transformedKind, err := expandDnsManagedZoneDnssecConfigKind(original["kind"], d, config)
if err != nil {
return nil, err
} else if val := reflect.ValueOf(transformedKind); val.IsValid() && !isEmptyValue(val) {
transformed["kind"] = transformedKind
}

transformedNonExistence, err := expandDnsManagedZoneDnssecConfigNonExistence(original["non_existence"], d, config)
if err != nil {
return nil, err
} else if val := reflect.ValueOf(transformedNonExistence); val.IsValid() && !isEmptyValue(val) {
transformed["nonExistence"] = transformedNonExistence
}

transformedState, err := expandDnsManagedZoneDnssecConfigState(original["state"], d, config)
if err != nil {
return nil, err
} else if val := reflect.ValueOf(transformedState); val.IsValid() && !isEmptyValue(val) {
transformed["state"] = transformedState
}

transformedDefaultKeySpecs, err := expandDnsManagedZoneDnssecConfigDefaultKeySpecs(original["default_key_specs"], d, config)
if err != nil {
return nil, err
} else if val := reflect.ValueOf(transformedDefaultKeySpecs); val.IsValid() && !isEmptyValue(val) {
transformed["defaultKeySpecs"] = transformedDefaultKeySpecs
}

return transformed, nil
}

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

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

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

func expandDnsManagedZoneDnssecConfigDefaultKeySpecs(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
l := v.([]interface{})
req := make([]interface{}, 0, len(l))
for _, raw := range l {
if raw == nil {
continue
}
original := raw.(map[string]interface{})
transformed := make(map[string]interface{})

transformedAlgorithm, err := expandDnsManagedZoneDnssecConfigDefaultKeySpecsAlgorithm(original["algorithm"], d, config)
if err != nil {
return nil, err
} else if val := reflect.ValueOf(transformedAlgorithm); val.IsValid() && !isEmptyValue(val) {
transformed["algorithm"] = transformedAlgorithm
}

transformedKeyLength, err := expandDnsManagedZoneDnssecConfigDefaultKeySpecsKeyLength(original["key_length"], d, config)
if err != nil {
return nil, err
} else if val := reflect.ValueOf(transformedKeyLength); val.IsValid() && !isEmptyValue(val) {
transformed["keyLength"] = transformedKeyLength
}

transformedKeyType, err := expandDnsManagedZoneDnssecConfigDefaultKeySpecsKeyType(original["key_type"], d, config)
if err != nil {
return nil, err
} else if val := reflect.ValueOf(transformedKeyType); val.IsValid() && !isEmptyValue(val) {
transformed["keyType"] = transformedKeyType
}

transformedKind, err := expandDnsManagedZoneDnssecConfigDefaultKeySpecsKind(original["kind"], d, config)
if err != nil {
return nil, err
} else if val := reflect.ValueOf(transformedKind); val.IsValid() && !isEmptyValue(val) {
transformed["kind"] = transformedKind
}

req = append(req, transformed)
}
return req, nil
}

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

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

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

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

func expandDnsManagedZoneName(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
return v, nil
}
Expand Down
8 changes: 8 additions & 0 deletions google-beta/resource_dns_managed_zone_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,14 @@ resource "google_dns_managed_zone" "private" {
networks {
network_url = "${google_compute_network.%s.self_link}"
}
dnssec_config {
state = "on"
default_key_specs {
algorithm = "rsasha1"
key_length = "128"
key_type = "zoneSigning"
}
}
}
}
Expand Down
41 changes: 41 additions & 0 deletions website/docs/r/dns_managed_zone.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,10 @@ The following arguments are supported:
(Optional)
A textual description field. Defaults to 'Managed by Terraform'.

* `dnssec_config` -
(Optional)
DNSSEC configuration Structure is documented below.

* `labels` -
(Optional)
A set of key/value label pairs to assign to this ManagedZone.
Expand Down Expand Up @@ -242,6 +246,43 @@ The following arguments are supported:
If it is not provided, the provider project is used.


The `dnssec_config` block supports:

* `kind` -
(Optional)
Identifies what kind of resource this is

* `non_existence` -
(Optional)
Specifies the mechanism used to provide authenticated denial-of-existence responses. Output only while state is not OFF.

* `state` -
(Optional)
Specifies whether DNSSEC is enabled, and what mode it is in

* `default_key_specs` -
(Optional)
Specifies parameters that will be used for generating initial DnsKeys for this ManagedZone. Output only while state is not OFF Structure is documented below.


The `default_key_specs` block supports:

* `algorithm` -
(Optional)
String mnemonic specifying the DNSSEC algorithm of this key

* `key_length` -
(Optional)
Length of the keys in bits

* `key_type` -
(Optional)
Specifies whether this is a key signing key (KSK) or a zone signing key (ZSK). Key signing keys have the Secure Entry Point flag set and, when active, will only be used to sign resource record sets of type DNSKEY. Zone signing keys do not have the Secure Entry Point flag set and will be used to sign all other types of resource record sets.

* `kind` -
(Optional)
Identifies what kind of resource this is

The `private_visibility_config` block supports:

* `networks` -
Expand Down

0 comments on commit 5543452

Please sign in to comment.