diff --git a/google/resource_dataproc_cluster.go b/google/resource_dataproc_cluster.go index 6b3be489ed3..ffb24ea2a68 100644 --- a/google/resource_dataproc_cluster.go +++ b/google/resource_dataproc_cluster.go @@ -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", @@ -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, @@ -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) } @@ -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 { @@ -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), @@ -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, diff --git a/google/resource_dataproc_cluster_test.go b/google/resource_dataproc_cluster_test.go index 070cc001016..e86edecc2fc 100644 --- a/google/resource_dataproc_cluster_test.go +++ b/google/resource_dataproc_cluster_test.go @@ -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) @@ -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) +} diff --git a/google/resource_sql_database_instance_test.go b/google/resource_sql_database_instance_test.go index 4c96a3d03b9..402fe1699bc 100644 --- a/google/resource_sql_database_instance_test.go +++ b/google/resource_sql_database_instance_test.go @@ -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" ) diff --git a/website/docs/r/dataproc_cluster.html.markdown b/website/docs/r/dataproc_cluster.html.markdown index 61b5cea596b..a94fb5cbd54 100644 --- a/website/docs/r/dataproc_cluster.html.markdown +++ b/website/docs/r/dataproc_cluster.html.markdown @@ -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. @@ -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