diff --git a/google-beta/resource_container_cluster.go b/google-beta/resource_container_cluster.go index d0c8bceae9..6f0d93c5f9 100644 --- a/google-beta/resource_container_cluster.go +++ b/google-beta/resource_container_cluster.go @@ -687,6 +687,26 @@ func resourceContainerCluster() *schema.Resource { }, }, + "release_channel": { + Type: schema.TypeList, + ForceNew: true, + Optional: true, + Computed: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "channel": { + Type: schema.TypeString, + Default: "UNSPECIFIED", + Optional: true, + ForceNew: true, + ValidateFunc: validation.StringInSlice([]string{"UNSPECIFIED", "RAPID", "REGULAR", "STABLE"}, false), + DiffSuppressFunc: emptyOrDefaultStringSuppress("UNSPECIFIED"), + }, + }, + }, + }, + "resource_labels": { Type: schema.TypeMap, Optional: true, @@ -922,6 +942,7 @@ func resourceContainerClusterCreate(d *schema.ResourceData, meta interface{}) er EnableKubernetesAlpha: d.Get("enable_kubernetes_alpha").(bool), IpAllocationPolicy: expandIPAllocationPolicy(d.Get("ip_allocation_policy")), PodSecurityPolicyConfig: expandPodSecurityPolicyConfig(d.Get("pod_security_policy_config")), + ReleaseChannel: expandReleaseChannel(d.Get("release_channel")), ShieldedNodes: &containerBeta.ShieldedNodes{ Enabled: d.Get("enable_shielded_nodes").(bool), ForceSendFields: []string{"Enabled"}, @@ -1183,6 +1204,9 @@ func resourceContainerClusterRead(d *schema.ResourceData, meta interface{}) erro if err := d.Set("authenticator_groups_config", flattenAuthenticatorGroupsConfig(cluster.AuthenticatorGroupsConfig)); err != nil { return err } + if err := d.Set("release_channel", flattenReleaseChannel(cluster.ReleaseChannel)); err != nil { + return err + } d.Set("enable_intranode_visibility", cluster.NetworkConfig.EnableIntraNodeVisibility) if cluster.DefaultMaxPodsConstraint != nil { d.Set("default_max_pods_per_node", cluster.DefaultMaxPodsConstraint.MaxPodsPerNode) @@ -2299,6 +2323,17 @@ func expandPrivateClusterConfig(configured interface{}) *containerBeta.PrivateCl } } +func expandReleaseChannel(configured interface{}) *containerBeta.ReleaseChannel { + l := configured.([]interface{}) + if len(l) == 0 || l[0] == nil { + return nil + } + config := l[0].(map[string]interface{}) + return &containerBeta.ReleaseChannel{ + Channel: config["channel"].(string), + } +} + func expandDatabaseEncryption(configured interface{}) *containerBeta.DatabaseEncryption { l := configured.([]interface{}) if len(l) == 0 { @@ -2491,6 +2526,21 @@ func flattenPrivateClusterConfig(c *containerBeta.PrivateClusterConfig) []map[st } } +func flattenReleaseChannel(c *containerBeta.ReleaseChannel) []map[string]interface{} { + result := []map[string]interface{}{} + if c != nil { + result = append(result, map[string]interface{}{ + "channel": c.Channel, + }) + } else { + // Explicitly set the network policy to the default. + result = append(result, map[string]interface{}{ + "channel": "UNSPECIFIED", + }) + } + return result +} + func flattenVerticalPodAutoscaling(c *containerBeta.VerticalPodAutoscaling) []map[string]interface{} { if c == nil { return nil diff --git a/google-beta/resource_container_cluster_test.go b/google-beta/resource_container_cluster_test.go index ef95b2eb31..0c04a73028 100644 --- a/google-beta/resource_container_cluster_test.go +++ b/google-beta/resource_container_cluster_test.go @@ -357,6 +357,66 @@ func TestAccContainerCluster_withNetworkPolicyEnabled(t *testing.T) { }) } +func TestAccContainerCluster_withReleaseChannelEnabled(t *testing.T) { + t.Parallel() + clusterName := fmt.Sprintf("cluster-test-%s", acctest.RandString(10)) + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckContainerClusterDestroy, + Steps: []resource.TestStep{ + { + Config: testAccContainerCluster_withReleaseChannelEnabled(clusterName, "STABLE"), + }, + { + ResourceName: "google_container_cluster.with_release_channel", + ImportStateIdPrefix: "us-central1-a/", + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccContainerCluster_withReleaseChannelEnabled(clusterName, "REGULAR"), + }, + { + ResourceName: "google_container_cluster.with_release_channel", + ImportStateIdPrefix: "us-central1-a/", + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccContainerCluster_withReleaseChannelEnabled(clusterName, "RAPID"), + }, + { + ResourceName: "google_container_cluster.with_release_channel", + ImportStateIdPrefix: "us-central1-a/", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccContainerCluster_withReleaseChannelDisabled(t *testing.T) { + t.Parallel() + clusterName := fmt.Sprintf("cluster-test-%s", acctest.RandString(10)) + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckContainerClusterDestroy, + Steps: []resource.TestStep{ + { + Config: testAccContainerCluster_withReleaseChannelDisabled(clusterName), + }, + { + ResourceName: "google_container_cluster.with_release_channel", + ImportStateIdPrefix: "us-central1-a/", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func TestAccContainerCluster_withMasterAuthorizedNetworksConfig(t *testing.T) { t.Parallel() @@ -1944,6 +2004,30 @@ resource "google_container_cluster" "with_network_policy_enabled" { }`, clusterName) } +func testAccContainerCluster_withReleaseChannelEnabled(clusterName string, channel string) string { + return fmt.Sprintf(` +resource "google_container_cluster" "with_release_channel" { + name = "%s" + location = "us-central1-a" + initial_node_count = 1 + + release_channel { + channel = "%s" + } +}`, clusterName, channel) +} + +func testAccContainerCluster_withReleaseChannelDisabled(clusterName string) string { + return fmt.Sprintf(` +resource "google_container_cluster" "with_release_channel" { + name = "%s" + location = "us-central1-a" + initial_node_count = 1 + + release_channel {} +}`, clusterName) +} + func testAccContainerCluster_removeNetworkPolicy(clusterName string) string { return fmt.Sprintf(` resource "google_container_cluster" "with_network_policy_enabled" { diff --git a/website/docs/d/datasource_tpu_tensorflow_versions.html.markdown b/website/docs/d/datasource_tpu_tensorflow_versions.html.markdown index a9592fb0fa..1ba803ebf1 100644 --- a/website/docs/d/datasource_tpu_tensorflow_versions.html.markdown +++ b/website/docs/d/datasource_tpu_tensorflow_versions.html.markdown @@ -39,10 +39,10 @@ The following arguments are supported: is not provided, the provider project is used. * `zone` - (Optional) The zone to list versions for. If it - is not provided, the project zone is used. + is not provided, the provider zone is used. ## Attributes Reference The following attributes are exported: -* `versions` - The list of TensorFlow versions available for the given project and zone. \ No newline at end of file +* `versions` - The list of TensorFlow versions available for the given project and zone. diff --git a/website/docs/r/container_cluster.html.markdown b/website/docs/r/container_cluster.html.markdown index 708f771530..8c23eb42b4 100644 --- a/website/docs/r/container_cluster.html.markdown +++ b/website/docs/r/container_cluster.html.markdown @@ -156,7 +156,7 @@ in this cluster in CIDR notation (e.g. 10.96.0.0/14). Leave blank to have one automatically chosen or specify a /14 block in 10.0.0.0/8. This field will only work if your cluster is not VPC-native- when an `ip_allocation_policy` block is not defined, or `ip_allocation_policy.use_ip_aliases` is set to false. If your -cluster is VPC-native, use `ip_allocation_policy.cluster_ipv4_cidr_block`. +cluster is VPC-native, use `ip_allocation_policy.cluster_ipv4_cidr_block`. * `cluster_autoscaling` - (Optional, [Beta](https://terraform.io/docs/providers/google/provider_versions.html)) Per-cluster configuration of Node Auto-Provisioning with Cluster Autoscaler to @@ -290,6 +290,10 @@ to the datasource. A `region` can have a different set of supported versions tha * `project` - (Optional) The ID of the project in which the resource belongs. If it is not provided, the provider project is used. +* `release_channel` - (Optional, [Beta](https://terraform.io/docs/providers/google/provider_versions.html)) Configuration options for the + [Release channel](https://cloud.google.com/kubernetes-engine/docs/concepts/release-channels) + feature, which provide more control over automatic upgrades of your GKE clusters. Structure is documented below. + * `remove_default_node_pool` - (Optional) If `true`, deletes the default node pool upon cluster creation. If you're using `google_container_node_pool` resources with no default node pool, this should be set to `true`, alongside @@ -434,7 +438,7 @@ to have a range chosen with a specific netmask. Set to a CIDR notation (e.g. 10. from the RFC-1918 private networks (e.g. 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) to pick a specific range to use. This field will only work if your cluster is VPC-native- when `ip_allocation_policy.use_ip_aliases` is undefined or set to -true. If your cluster is not VPC-native, use `cluster_ipv4_cidr`. +true. If your cluster is not VPC-native, use `cluster_ipv4_cidr`. * `node_ipv4_cidr_block` - (Optional) The IP address range of the node IPs in this cluster. This should be set only if `create_subnetwork` is true. @@ -548,7 +552,7 @@ The `node_config` block supports: are preemptible. See the [official documentation](https://cloud.google.com/container-engine/docs/preemptible-vm) for more information. Defaults to false. -* `sandbox_config` - (Optional, [Beta](https://terraform.io/docs/providers/google/provider_versions.html)) [GKE Sandbox](https://cloud.google.com/kubernetes-engine/docs/how-to/sandbox-pods) configuration. When enabling this feature you must specify `image_type = "COS_CONTAINERD"` and `node_version = "1.12.7-gke.17"` or later to use it. +* `sandbox_config` - (Optional, [Beta](https://terraform.io/docs/providers/google/provider_versions.html)) [GKE Sandbox](https://cloud.google.com/kubernetes-engine/docs/how-to/sandbox-pods) configuration. When enabling this feature you must specify `image_type = "COS_CONTAINERD"` and `node_version = "1.12.7-gke.17"` or later to use it. Structure is documented below. * `service_account` - (Optional) The service account to be used by the Node VMs. @@ -615,6 +619,15 @@ The `sandbox_type` block supports: * `"gvisor"`: Pods run within a gVisor sandbox. +The `release_channel` block supports: + +* `channel` - (Optional) The selected release channel. Defaults to `UNSPECIFIED`. + Accepted values are: + * UNSPECIFIED: Not set. + * RAPID: Weekly upgrade cadence; Early testers and developers who requires new features. + * REGULAR: Multiple per month upgrade cadence; Production users who need features not yet offered in the Stable channel. + * STABLE: Every few months upgrade cadence; Production users who need stability above all else, and for whom frequent upgrades are too risky. + The `resource_usage_export_config` block supports: * `enable_network_egress_metering` (Optional) - Whether to enable network egress metering for this cluster. If enabled, a daemonset will be created