Skip to content

Commit

Permalink
lifecycle_config and endpoint_config to ga (#6281) (#12129)
Browse files Browse the repository at this point in the history
Signed-off-by: Modular Magician <magic-modules@google.com>
  • Loading branch information
modular-magician authored Jul 19, 2022
1 parent 1f5bdd2 commit ab794f7
Show file tree
Hide file tree
Showing 4 changed files with 270 additions and 2 deletions.
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

0 comments on commit ab794f7

Please sign in to comment.