Skip to content

Commit

Permalink
Add security_config to dataproc cluster
Browse files Browse the repository at this point in the history
Signed-off-by: Modular Magician <[email protected]>
  • Loading branch information
Ty Larrabee authored and modular-magician committed Dec 12, 2019
1 parent 1c8391d commit 1f0a978
Show file tree
Hide file tree
Showing 4 changed files with 313 additions and 0 deletions.
197 changes: 197 additions & 0 deletions google/resource_dataproc_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ var (
"cluster_config.0.master_config",
"cluster_config.0.worker_config",
"cluster_config.0.preemptible_worker_config",
"cluster_config.0.security_config",
"cluster_config.0.software_config",
"cluster_config.0.initialization_action",
"cluster_config.0.encryption_config",
Expand Down Expand Up @@ -303,6 +304,105 @@ func resourceDataprocCluster() *schema.Resource {
},
},

"security_config": {
Type: schema.TypeList,
Optional: true,
Description: "Security related configuration",
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"kerberos_config": {
Type: schema.TypeList,
Required: true,
Description: "Kerberos related configuration",
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"cross_realm_trust_admin_server": {
Type: schema.TypeString,
Optional: true,
Description: `The admin server (IP or hostname) for the remote trusted realm in a cross realm trust relationship.`,
},
"cross_realm_trust_kdc": {
Type: schema.TypeString,
Optional: true,
Description: `The KDC (IP or hostname) for the remote trusted realm in a cross realm trust relationship.`,
},
"cross_realm_trust_realm": {
Type: schema.TypeString,
Optional: true,
Description: `The remote realm the Dataproc on-cluster KDC will trust, should the user enable cross realm trust.`,
},
"cross_realm_trust_shared_password_uri": {
Type: schema.TypeString,
Optional: true,
Description: `The Cloud Storage URI of a KMS encrypted file containing the shared password between the on-cluster
Kerberos realm and the remote trusted realm, in a cross realm trust relationship.`,
},
"enable_kerberos": {
Type: schema.TypeBool,
Optional: true,
Description: `Flag to indicate whether to Kerberize the cluster.`,
},
"kdc_db_key_uri": {
Type: schema.TypeString,
Optional: true,
Description: `The Cloud Storage URI of a KMS encrypted file containing the master key of the KDC database.`,
},
"key_password_uri": {
Type: schema.TypeString,
Optional: true,
Description: `The Cloud Storage URI of a KMS encrypted file containing the password to the user provided key. For the self-signed certificate, this password is generated by Dataproc.`,
},
"keystore_uri": {
Type: schema.TypeString,
Optional: true,
Description: `The Cloud Storage URI of the keystore file used for SSL encryption. If not provided, Dataproc will provide a self-signed certificate.`,
},
"keystore_password_uri": {
Type: schema.TypeString,
Optional: true,
Description: `The Cloud Storage URI of a KMS encrypted file containing
the password to the user provided keystore. For the self-signed certificate, this password is generated
by Dataproc`,
},
"kms_key_uri": {
Type: schema.TypeString,
Required: true,
Description: `The uri of the KMS key used to encrypt various sensitive files.`,
},
"realm": {
Type: schema.TypeString,
Optional: true,
Description: `The name of the on-cluster Kerberos realm. If not specified, the uppercased domain of hostnames will be the realm.`,
},
"root_principal_password_uri": {
Type: schema.TypeString,
Required: true,
Description: `The cloud Storage URI of a KMS encrypted file containing the root principal password.`,
},
"tgt_lifetime_hours": {
Type: schema.TypeInt,
Optional: true,
Description: `The lifetime of the ticket granting ticket, in hours.`,
},
"truststore_password_uri": {
Type: schema.TypeString,
Optional: true,
Description: `The Cloud Storage URI of a KMS encrypted file containing the password to the user provided truststore. For the self-signed certificate, this password is generated by Dataproc.`,
},
"truststore_uri": {
Type: schema.TypeString,
Optional: true,
Description: `The Cloud Storage URI of the truststore file used for SSL encryption. If not provided, Dataproc will provide a self-signed certificate.`,
},
},
},
},
},
},
},

"software_config": {
Type: schema.TypeList,
Optional: true,
Expand Down Expand Up @@ -628,6 +728,10 @@ func expandClusterConfig(d *schema.ResourceData, config *Config) (*dataproc.Clus
}
conf.GceClusterConfig = c

if cfg, ok := configOptions(d, "cluster_config.0.security_config"); ok {
conf.SecurityConfig = expandSecurityConfig(cfg)
}

if cfg, ok := configOptions(d, "cluster_config.0.software_config"); ok {
conf.SoftwareConfig = expandSoftwareConfig(cfg)
}
Expand Down Expand Up @@ -715,6 +819,65 @@ func expandGceClusterConfig(d *schema.ResourceData, config *Config) (*dataproc.G
return conf, nil
}

func expandSecurityConfig(cfg map[string]interface{}) *dataproc.SecurityConfig {
conf := &dataproc.SecurityConfig{}
if kfg, ok := cfg["kerberos_config"]; ok {
conf.KerberosConfig = expandKerberosConfig(kfg.([]interface{})[0].(map[string]interface{}))
}
return conf
}

func expandKerberosConfig(cfg map[string]interface{}) *dataproc.KerberosConfig {
conf := &dataproc.KerberosConfig{}
if v, ok := cfg["enable_kerberos"]; ok {
conf.EnableKerberos = v.(bool)
}
if v, ok := cfg["root_principal_password_uri"]; ok {
conf.RootPrincipalPasswordUri = v.(string)
}
if v, ok := cfg["kms_key_uri"]; ok {
conf.KmsKeyUri = v.(string)
}
if v, ok := cfg["keystore_uri"]; ok {
conf.KeystoreUri = v.(string)
}
if v, ok := cfg["truststore_uri"]; ok {
conf.TruststoreUri = v.(string)
}
if v, ok := cfg["keystore_password_uri"]; ok {
conf.KeystorePasswordUri = v.(string)
}
if v, ok := cfg["key_password_uri"]; ok {
conf.KeyPasswordUri = v.(string)
}
if v, ok := cfg["truststore_password_uri"]; ok {
conf.TruststorePasswordUri = v.(string)
}
if v, ok := cfg["cross_realm_trust_realm"]; ok {
conf.CrossRealmTrustRealm = v.(string)
}
if v, ok := cfg["cross_realm_trust_kdc"]; ok {
conf.CrossRealmTrustKdc = v.(string)
}
if v, ok := cfg["cross_realm_trust_admin_server"]; ok {
conf.CrossRealmTrustAdminServer = v.(string)
}
if v, ok := cfg["cross_realm_trust_shared_password_uri"]; ok {
conf.CrossRealmTrustSharedPasswordUri = v.(string)
}
if v, ok := cfg["kdc_db_key_uri"]; ok {
conf.KdcDbKeyUri = v.(string)
}
if v, ok := cfg["tgt_lifetime_hours"]; ok {
conf.TgtLifetimeHours = int64(v.(int))
}
if v, ok := cfg["realm"]; ok {
conf.Realm = v.(string)
}

return conf
}

func expandSoftwareConfig(cfg map[string]interface{}) *dataproc.SoftwareConfig {
conf := &dataproc.SoftwareConfig{}
if v, ok := cfg["override_properties"]; ok {
Expand Down Expand Up @@ -961,6 +1124,7 @@ func flattenClusterConfig(d *schema.ResourceData, cfg *dataproc.ClusterConfig) (

"bucket": cfg.ConfigBucket,
"gce_cluster_config": flattenGceClusterConfig(d, cfg.GceClusterConfig),
"security_config": flattenSecurityConfig(d, cfg.SecurityConfig),
"software_config": flattenSoftwareConfig(d, cfg.SoftwareConfig),
"master_config": flattenInstanceGroupConfig(d, cfg.MasterConfig),
"worker_config": flattenInstanceGroupConfig(d, cfg.WorkerConfig),
Expand All @@ -979,6 +1143,39 @@ func flattenClusterConfig(d *schema.ResourceData, cfg *dataproc.ClusterConfig) (
return []map[string]interface{}{data}, nil
}

func flattenSecurityConfig(d *schema.ResourceData, sc *dataproc.SecurityConfig) []map[string]interface{} {
if sc == nil {
return nil
}
data := map[string]interface{}{
"kerberos_config": flattenKerberosConfig(d, sc.KerberosConfig),
}

return []map[string]interface{}{data}
}

func flattenKerberosConfig(d *schema.ResourceData, kfg *dataproc.KerberosConfig) []map[string]interface{} {
data := map[string]interface{}{
"enable_kerberos": kfg.EnableKerberos,
"root_principal_password_uri": kfg.RootPrincipalPasswordUri,
"kms_key_uri": kfg.KmsKeyUri,
"keystore_uri": kfg.KeystoreUri,
"truststore_uri": kfg.TruststoreUri,
"keystore_password_uri": kfg.KeystorePasswordUri,
"key_password_uri": kfg.KeyPasswordUri,
"truststore_password_uri": kfg.TruststorePasswordUri,
"cross_realm_trust_realm": kfg.CrossRealmTrustRealm,
"cross_realm_trust_kdc": kfg.CrossRealmTrustKdc,
"cross_realm_trust_admin_server": kfg.CrossRealmTrustAdminServer,
"cross_realm_trust_shared_password_uri": kfg.CrossRealmTrustSharedPasswordUri,
"kdc_db_key_uri": kfg.KdcDbKeyUri,
"tgt_lifetime_hours": kfg.TgtLifetimeHours,
"realm": kfg.Realm,
}

return []map[string]interface{}{data}
}

func flattenSoftwareConfig(d *schema.ResourceData, sc *dataproc.SoftwareConfig) []map[string]interface{} {
data := map[string]interface{}{
"image_version": sc.ImageVersion,
Expand Down
49 changes: 49 additions & 0 deletions google/resource_dataproc_cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,28 @@ func TestAccDataprocCluster_KMS(t *testing.T) {
})
}

func TestAccDataprocCluster_withKerberos(t *testing.T) {
t.Parallel()

rnd := acctest.RandString(10)
kms := BootstrapKMSKey(t)

var cluster dataproc.Cluster
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckDataprocClusterDestroy(),
Steps: []resource.TestStep{
{
Config: testAccDataprocCluster_withKerberos(rnd, kms.CryptoKey.Name),
Check: resource.ComposeTestCheckFunc(
testAccCheckDataprocClusterExists("google_dataproc_cluster.kerb", &cluster),
),
},
},
})
}

func testAccCheckDataprocClusterDestroy() resource.TestCheckFunc {
return func(s *terraform.State) error {
config := testAccProvider.Meta().(*Config)
Expand Down Expand Up @@ -1347,3 +1369,30 @@ resource "google_dataproc_cluster" "kms" {
}
`, pid, rnd, kmsKey)
}

func testAccDataprocCluster_withKerberos(rnd, kmsKey string) string {
return fmt.Sprintf(`
resource "google_storage_bucket" "bucket" {
name = "dproc-cluster-test-%s"
}
resource "google_storage_bucket_object" "password" {
name = "dataproc-password-%s"
bucket = google_storage_bucket.bucket.name
content = "hunter2"
}
resource "google_dataproc_cluster" "kerb" {
name = "dproc-cluster-test-%s"
region = "us-central1"
cluster_config {
security_config {
kerberos_config {
root_principal_password_uri = google_storage_bucket_object.password.self_link
kms_key_uri = "%s"
}
}
}
}
`, rnd, rnd, rnd, kmsKey)
}
1 change: 1 addition & 0 deletions google/resource_sql_database_instance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/helper/acctest"
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/terraform"

sqladmin "google.golang.org/api/sqladmin/v1beta4"
)

Expand Down
66 changes: 66 additions & 0 deletions website/docs/r/dataproc_cluster.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,8 @@ The `cluster_config` block supports:
* `software_config` (Optional) The config settings for software inside the cluster.
Structure defined below.

* `security_config` (Optional) Security related configuration. Structure defined below.

* `autoscaling_config` (Optional) The autoscaling policy config associated with the cluster.
Structure defined below.

Expand Down Expand Up @@ -427,6 +429,70 @@ cluster_config {

- - -

The `cluster_config.security_config` block supports:

```hcl
cluster_config {
# Override or set some custom properties
security_config {
kerberos_config {
kms_key_uri = "projects/projectId/locations/locationId/keyRings/keyRingId/cryptoKeys/keyId"
root_principal_password_uri = "bucketId/o/objectId"
}
}
}
```

* `kerberos_config` (Required) Kerberos Configuration

* `cross_realm_trust_admin_server` - (Optional) The admin server (IP or hostname) for the
remote trusted realm in a cross realm trust relationship.

* `cross_realm_trust_kdc` - (Optional) The KDC (IP or hostname) for the
remote trusted realm in a cross realm trust relationship.

* `cross_realm_trust_realm` - (Optional) The remote realm the Dataproc on-cluster KDC will
trust, should the user enable cross realm trust.

* `cross_realm_trust_shared_password_uri` - (Optional) The Cloud Storage URI of a KMS
encrypted file containing the shared password between the on-cluster Kerberos realm
and the remote trusted realm, in a cross realm trust relationship.

* `enable_kerberos` - (Optional) Flag to indicate whether to Kerberize the cluster.

* `kdc_db_key_uri` - (Optional) The Cloud Storage URI of a KMS encrypted file containing
the master key of the KDC database.

* `key_password_uri` - (Optional) The Cloud Storage URI of a KMS encrypted file containing
the password to the user provided key. For the self-signed certificate, this password
is generated by Dataproc.

* `keystore_uri` - (Optional) The Cloud Storage URI of the keystore file used for SSL encryption.
If not provided, Dataproc will provide a self-signed certificate.

* `keystore_password_uri` - (Optional) The Cloud Storage URI of a KMS encrypted file containing
the password to the user provided keystore. For the self-signed certificated, the password
is generated by Dataproc.

* `kms_key_uri` - (Required) The URI of the KMS key used to encrypt various sensitive files.

* `realm` - (Optional) The name of the on-cluster Kerberos realm. If not specified, the
uppercased domain of hostnames will be the realm.

* `root_principal_password_uri` - (Required) The Cloud Storage URI of a KMS encrypted file
containing the root principal password.

* `tgt_lifetime_hours` - (Optional) The lifetime of the ticket granting ticket, in hours.

* `truststore_password_uri` - (Optional) The Cloud Storage URI of a KMS encrypted file
containing the password to the user provided truststore. For the self-signed
certificate, this password is generated by Dataproc.

* `truststore_uri` - (Optional) The Cloud Storage URI of the truststore file used for
SSL encryption. If not provided, Dataproc will provide a self-signed certificate.

- - -

The `cluster_config.autoscaling_config` block supports:

```hcl
Expand Down

0 comments on commit 1f0a978

Please sign in to comment.