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

dataproc: promote lifecycle_config and endpoint_config to ga #12129

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/6281.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
dataproc: promote `lifecycle_config` and `endpoint_config` to ga in `google_dataproc_cluster`
```
141 changes: 141 additions & 0 deletions google/resource_dataproc_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ var (
"cluster_config.0.encryption_config",
"cluster_config.0.autoscaling_config",
"cluster_config.0.metastore_config",
"cluster_config.0.lifecycle_config",
"cluster_config.0.endpoint_config",
}
)

Expand Down Expand Up @@ -958,6 +960,68 @@ by Dataproc`,
},
},
},
"lifecycle_config": {
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
AtLeastOneOf: clusterConfigKeys,
Description: `The settings for auto deletion cluster schedule.`,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"idle_delete_ttl": {
Type: schema.TypeString,
Optional: true,
Description: `The duration to keep the cluster alive while idling (no jobs running). After this TTL, the cluster will be deleted. Valid range: [10m, 14d].`,
AtLeastOneOf: []string{
"cluster_config.0.lifecycle_config.0.idle_delete_ttl",
"cluster_config.0.lifecycle_config.0.auto_delete_time",
},
},
"idle_start_time": {
Type: schema.TypeString,
Computed: true,
Description: `Time when the cluster became idle (most recent job finished) and became eligible for deletion due to idleness.`,
},
// the API also has the auto_delete_ttl option in its request, however,
// the value is not returned in the response, rather the auto_delete_time
// after calculating ttl with the update time is returned, thus, for now
// we will only allow auto_delete_time to updated.
"auto_delete_time": {
Type: schema.TypeString,
Optional: true,
Description: `The time when cluster will be auto-deleted. A timestamp in RFC3339 UTC "Zulu" format, accurate to nanoseconds. Example: "2014-10-02T15:01:23.045123456Z".`,
DiffSuppressFunc: timestampDiffSuppress(time.RFC3339Nano),
AtLeastOneOf: []string{
"cluster_config.0.lifecycle_config.0.idle_delete_ttl",
"cluster_config.0.lifecycle_config.0.auto_delete_time",
},
},
},
},
},
"endpoint_config": {
Type: schema.TypeList,
Optional: true,
Computed: true,
MaxItems: 1,
Description: `The config settings for port access on the cluster. Structure defined below.`,
AtLeastOneOf: clusterConfigKeys,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"enable_http_port_access": {
Type: schema.TypeBool,
Required: true,
ForceNew: true,
Description: `The flag to enable http access to specific ports on the cluster from external sources (aka Component Gateway). Defaults to false.`,
},
"http_ports": {
Type: schema.TypeMap,
Computed: true,
Description: `The map of port descriptions to URLs. Will only be populated if enable_http_port_access is true.`,
},
},
},
},
},
},
},
Expand Down Expand Up @@ -1408,6 +1472,14 @@ func expandClusterConfig(d *schema.ResourceData, config *Config) (*dataproc.Clus
conf.MetastoreConfig = expandMetastoreConfig(cfg)
}

if cfg, ok := configOptions(d, "cluster_config.0.lifecycle_config"); ok {
conf.LifecycleConfig = expandLifecycleConfig(cfg)
}

if cfg, ok := configOptions(d, "cluster_config.0.endpoint_config"); ok {
conf.EndpointConfig = expandEndpointConfig(cfg)
}

if cfg, ok := configOptions(d, "cluster_config.0.master_config"); ok {
log.Println("[INFO] got master_config")
conf.MasterConfig = expandInstanceGroupConfig(cfg)
Expand Down Expand Up @@ -1587,6 +1659,25 @@ func expandAutoscalingConfig(cfg map[string]interface{}) *dataproc.AutoscalingCo
return conf
}

func expandLifecycleConfig(cfg map[string]interface{}) *dataproc.LifecycleConfig {
conf := &dataproc.LifecycleConfig{}
if v, ok := cfg["idle_delete_ttl"]; ok {
conf.IdleDeleteTtl = v.(string)
}
if v, ok := cfg["auto_delete_time"]; ok {
conf.AutoDeleteTime = v.(string)
}
return conf
}

func expandEndpointConfig(cfg map[string]interface{}) *dataproc.EndpointConfig {
conf := &dataproc.EndpointConfig{}
if v, ok := cfg["enable_http_port_access"]; ok {
conf.EnableHttpPortAccess = v.(bool)
}
return conf
}

func expandMetastoreConfig(cfg map[string]interface{}) *dataproc.MetastoreConfig {
conf := &dataproc.MetastoreConfig{}
if v, ok := cfg["dataproc_metastore_service"]; ok {
Expand Down Expand Up @@ -1756,6 +1847,28 @@ func resourceDataprocClusterUpdate(d *schema.ResourceData, meta interface{}) err
updMask = append(updMask, "config.autoscaling_config.policy_uri")
}

if d.HasChange("cluster_config.0.lifecycle_config.0.idle_delete_ttl") {
idleDeleteTtl := d.Get("cluster_config.0.lifecycle_config.0.idle_delete_ttl").(string)
cluster.Config.LifecycleConfig = &dataproc.LifecycleConfig{
IdleDeleteTtl: idleDeleteTtl,
}

updMask = append(updMask, "config.lifecycle_config.idle_delete_ttl")
}

if d.HasChange("cluster_config.0.lifecycle_config.0.auto_delete_time") {
desiredDeleteTime := d.Get("cluster_config.0.lifecycle_config.0.auto_delete_time").(string)
if cluster.Config.LifecycleConfig != nil {
cluster.Config.LifecycleConfig.AutoDeleteTime = desiredDeleteTime
} else {
cluster.Config.LifecycleConfig = &dataproc.LifecycleConfig{
AutoDeleteTime: desiredDeleteTime,
}
}

updMask = append(updMask, "config.lifecycle_config.auto_delete_time")
}

if len(updMask) > 0 {
gracefulDecommissionTimeout := d.Get("graceful_decommission_timeout").(string)

Expand Down Expand Up @@ -1972,6 +2085,8 @@ func flattenClusterConfig(d *schema.ResourceData, cfg *dataproc.ClusterConfig) (
"security_config": flattenSecurityConfig(d, cfg.SecurityConfig),
"preemptible_worker_config": flattenPreemptibleInstanceGroupConfig(d, cfg.SecondaryWorkerConfig),
"metastore_config": flattenMetastoreConfig(d, cfg.MetastoreConfig),
"lifecycle_config": flattenLifecycleConfig(d, cfg.LifecycleConfig),
"endpoint_config": flattenEndpointConfig(d, cfg.EndpointConfig),
}

if len(cfg.InitializationActions) > 0 {
Expand Down Expand Up @@ -2052,6 +2167,32 @@ func flattenAutoscalingConfig(d *schema.ResourceData, ec *dataproc.AutoscalingCo
return []map[string]interface{}{data}
}

func flattenLifecycleConfig(d *schema.ResourceData, lc *dataproc.LifecycleConfig) []map[string]interface{} {
if lc == nil {
return nil
}

data := map[string]interface{}{
"idle_delete_ttl": lc.IdleDeleteTtl,
"auto_delete_time": lc.AutoDeleteTime,
}

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

func flattenEndpointConfig(d *schema.ResourceData, ec *dataproc.EndpointConfig) []map[string]interface{} {
if ec == nil {
return nil
}

data := map[string]interface{}{
"enable_http_port_access": ec.EnableHttpPortAccess,
"http_ports": ec.HttpPorts,
}

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

func flattenMetastoreConfig(d *schema.ResourceData, ec *dataproc.MetastoreConfig) []map[string]interface{} {
if ec == nil {
return nil
Expand Down
124 changes: 124 additions & 0 deletions google/resource_dataproc_cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"strconv"
"strings"
"testing"
"time"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
Expand Down Expand Up @@ -634,6 +635,63 @@ func TestAccDataprocCluster_withOptionalComponents(t *testing.T) {
})
}

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

rnd := randString(t, 10)
var cluster dataproc.Cluster
vcrTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckDataprocClusterDestroy(t),
Steps: []resource.TestStep{
{
Config: testAccDataprocCluster_withLifecycleConfigIdleDeleteTtl(rnd, "600s"),
Check: resource.ComposeTestCheckFunc(
testAccCheckDataprocClusterExists(t, "google_dataproc_cluster.with_lifecycle_config", &cluster),
),
},
{
Config: testAccDataprocCluster_withLifecycleConfigIdleDeleteTtl(rnd, "610s"),
Check: resource.ComposeTestCheckFunc(
testAccCheckDataprocClusterExists(t, "google_dataproc_cluster.with_lifecycle_config", &cluster),
),
},
},
})
}

func TestAccDataprocCluster_withLifecycleConfigAutoDeletion(t *testing.T) {
// Uses time.Now
skipIfVcr(t)
t.Parallel()

rnd := randString(t, 10)
now := time.Now()
fmtString := "2006-01-02T15:04:05.072Z"

var cluster dataproc.Cluster
vcrTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckDataprocClusterDestroy(t),
Steps: []resource.TestStep{
{
Config: testAccDataprocCluster_withLifecycleConfigAutoDeletionTime(rnd, now.Add(time.Hour*10).Format(fmtString)),
Check: resource.ComposeTestCheckFunc(
testAccCheckDataprocClusterExists(t, "google_dataproc_cluster.with_lifecycle_config", &cluster),
),
},
{
Config: testAccDataprocCluster_withLifecycleConfigAutoDeletionTime(rnd, now.Add(time.Hour*20).Format(fmtString)),
Check: resource.ComposeTestCheckFunc(
testAccCheckDataprocClusterExists(t, "google_dataproc_cluster.with_lifecycle_config", &cluster),
),
},
},
})
}

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

Expand Down Expand Up @@ -683,6 +741,27 @@ func TestAccDataprocCluster_withNetworkRefs(t *testing.T) {
})
}

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

var cluster dataproc.Cluster
rnd := randString(t, 10)
vcrTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckDataprocClusterDestroy(t),
Steps: []resource.TestStep{
{
Config: testAccDataprocCluster_withEndpointConfig(rnd),
Check: resource.ComposeTestCheckFunc(
testAccCheckDataprocClusterExists(t, "google_dataproc_cluster.with_endpoint_config", &cluster),
resource.TestCheckResourceAttr("google_dataproc_cluster.with_endpoint_config", "cluster_config.0.endpoint_config.0.enable_http_port_access", "true"),
),
},
},
})
}

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

Expand Down Expand Up @@ -1510,6 +1589,21 @@ resource "google_dataproc_cluster" "with_labels" {
`, rnd)
}

func testAccDataprocCluster_withEndpointConfig(rnd string) string {
return fmt.Sprintf(`
resource "google_dataproc_cluster" "with_endpoint_config" {
name = "tf-test-%s"
region = "us-central1"
cluster_config {
endpoint_config {
enable_http_port_access = "true"
}
}
}
`, rnd)
}

func testAccDataprocCluster_withImageVersion(rnd, version string) string {
return fmt.Sprintf(`
resource "google_dataproc_cluster" "with_image_version" {
Expand Down Expand Up @@ -1540,6 +1634,36 @@ resource "google_dataproc_cluster" "with_opt_components" {
`, rnd)
}

func testAccDataprocCluster_withLifecycleConfigIdleDeleteTtl(rnd, tm string) string {
return fmt.Sprintf(`
resource "google_dataproc_cluster" "with_lifecycle_config" {
name = "tf-test-dproc-%s"
region = "us-central1"
cluster_config {
lifecycle_config {
idle_delete_ttl = "%s"
}
}
}
`, rnd, tm)
}

func testAccDataprocCluster_withLifecycleConfigAutoDeletionTime(rnd, tm string) string {
return fmt.Sprintf(`
resource "google_dataproc_cluster" "with_lifecycle_config" {
name = "tf-test-dproc-%s"
region = "us-central1"
cluster_config {
lifecycle_config {
auto_delete_time = "%s"
}
}
}
`, rnd, tm)
}

func testAccDataprocCluster_withServiceAcc(sa string, rnd string) string {
return fmt.Sprintf(`
data "google_project" "project" {}
Expand Down
4 changes: 2 additions & 2 deletions website/docs/r/dataproc_cluster.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -368,10 +368,10 @@ resource "google_dataproc_cluster" "accelerated_cluster" {
* `encryption_config` (Optional) The Customer managed encryption keys settings for the cluster.
Structure [defined below](#nested_encryption_config).

* `lifecycle_config` (Optional, Beta) The settings for auto deletion cluster schedule.
* `lifecycle_config` (Optional) The settings for auto deletion cluster schedule.
Structure [defined below](#nested_lifecycle_config).

* `endpoint_config` (Optional, Beta) The config settings for port access on the cluster.
* `endpoint_config` (Optional) The config settings for port access on the cluster.
Structure [defined below](#nested_endpoint_config).

* `metastore_config` (Optional) The config setting for metastore service with the cluster.
Expand Down